aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2012-05-18 00:46:40 -0400
committerLuciano Coelho <coelho@ti.com>2012-06-06 12:28:05 -0400
commita1c597f2b22cdc228de3c58784b00e80b9b53e03 (patch)
treeeac1d01f867fd3f8df77fae3b050dba94c95e5b9 /drivers
parent2c38849f4a247673c8203a569444042e32d82410 (diff)
wlcore/wl12xx/wl18xx: implement op_set_key per HW arch
The 12xx set_key just calls the common wlcore_set_key function, in order to program the keys into the FW. The 18xx variant changes the spare block count when a GEM or TKIP key is set. Also modify the get_spare_blocks HW op for 18xx to return the correct numbers of spare blocks, according to what is currently set in FW. 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.c9
-rw-r--r--drivers/net/wireless/ti/wl18xx/acx.c4
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c96
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h12
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c14
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c3
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.h1
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h8
9 files changed, 136 insertions, 14 deletions
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 03ff1ce56bb4..2f6a39bfcf18 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -1369,6 +1369,14 @@ static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1369 return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; 1369 return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
1370} 1370}
1371 1371
1372static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1373 struct ieee80211_vif *vif,
1374 struct ieee80211_sta *sta,
1375 struct ieee80211_key_conf *key_conf)
1376{
1377 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1378}
1379
1372static struct wlcore_ops wl12xx_ops = { 1380static struct wlcore_ops wl12xx_ops = {
1373 .identify_chip = wl12xx_identify_chip, 1381 .identify_chip = wl12xx_identify_chip,
1374 .identify_fw = wl12xx_identify_fw, 1382 .identify_fw = wl12xx_identify_fw,
@@ -1393,6 +1401,7 @@ static struct wlcore_ops wl12xx_ops = {
1393 .ap_get_mimo_wide_rate_mask = NULL, 1401 .ap_get_mimo_wide_rate_mask = NULL,
1394 .debugfs_init = wl12xx_debugfs_add_files, 1402 .debugfs_init = wl12xx_debugfs_add_files,
1395 .get_spare_blocks = wl12xx_get_spare_blocks, 1403 .get_spare_blocks = wl12xx_get_spare_blocks,
1404 .set_key = wl12xx_set_key,
1396}; 1405};
1397 1406
1398static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { 1407static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c
index 3379db23a165..01ba40321435 100644
--- a/drivers/net/wireless/ti/wl18xx/acx.c
+++ b/drivers/net/wireless/ti/wl18xx/acx.c
@@ -32,6 +32,10 @@ int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap,
32 struct wl18xx_acx_host_config_bitmap *bitmap_conf; 32 struct wl18xx_acx_host_config_bitmap *bitmap_conf;
33 int ret; 33 int ret;
34 34
35 wl1271_debug(DEBUG_ACX, "acx cfg bitmap %d blk %d spare %d field %d",
36 host_cfg_bitmap, sdio_blk_size, extra_mem_blks,
37 len_field_size);
38
35 bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL); 39 bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
36 if (!bitmap_conf) { 40 if (!bitmap_conf) {
37 ret = -ENOMEM; 41 ret = -ENOMEM;
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index c651f872d7d5..9e5ce569f8da 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -848,17 +848,12 @@ static void wl18xx_tx_immediate_completion(struct wl1271 *wl)
848 wl18xx_tx_immediate_complete(wl); 848 wl18xx_tx_immediate_complete(wl);
849} 849}
850 850
851static int wl18xx_hw_init(struct wl1271 *wl) 851static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk)
852{ 852{
853 int ret; 853 int ret;
854 struct wl18xx_priv *priv = wl->priv;
855 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE |
856 HOST_IF_CFG_ADD_RX_ALIGNMENT;
857
858 u32 sdio_align_size = 0; 854 u32 sdio_align_size = 0;
859 855 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE |
860 /* (re)init private structures. Relevant on recovery as well. */ 856 HOST_IF_CFG_ADD_RX_ALIGNMENT;
861 priv->last_fw_rls_idx = 0;
862 857
863 /* Enable Tx SDIO padding */ 858 /* Enable Tx SDIO padding */
864 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) { 859 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) {
@@ -873,12 +868,28 @@ static int wl18xx_hw_init(struct wl1271 *wl)
873 } 868 }
874 869
875 ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap, 870 ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap,
876 sdio_align_size, 871 sdio_align_size, extra_mem_blk,
877 WL18XX_TX_HW_EXTRA_BLOCK_SPARE,
878 WL18XX_HOST_IF_LEN_SIZE_FIELD); 872 WL18XX_HOST_IF_LEN_SIZE_FIELD);
879 if (ret < 0) 873 if (ret < 0)
880 return ret; 874 return ret;
881 875
876 return 0;
877}
878
879static int wl18xx_hw_init(struct wl1271 *wl)
880{
881 int ret;
882 struct wl18xx_priv *priv = wl->priv;
883
884 /* (re)init private structures. Relevant on recovery as well. */
885 priv->last_fw_rls_idx = 0;
886 priv->extra_spare_vif_count = 0;
887
888 /* set the default amount of spare blocks in the bitmap */
889 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
890 if (ret < 0)
891 return ret;
892
882 if (checksum_param) { 893 if (checksum_param) {
883 ret = wl18xx_acx_set_checksum_state(wl); 894 ret = wl18xx_acx_set_checksum_state(wl);
884 if (ret != 0) 895 if (ret != 0)
@@ -1036,8 +1047,68 @@ static int wl18xx_handle_static_data(struct wl1271 *wl,
1036 1047
1037static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) 1048static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1038{ 1049{
1039 /* TODO: dynamically change to extra only when we have GEM or TKIP */ 1050 struct wl18xx_priv *priv = wl->priv;
1040 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; 1051
1052 /* If we have VIFs requiring extra spare, indulge them */
1053 if (priv->extra_spare_vif_count)
1054 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1055
1056 return WL18XX_TX_HW_BLOCK_SPARE;
1057}
1058
1059static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1060 struct ieee80211_vif *vif,
1061 struct ieee80211_sta *sta,
1062 struct ieee80211_key_conf *key_conf)
1063{
1064 struct wl18xx_priv *priv = wl->priv;
1065 bool change_spare = false;
1066 int ret;
1067
1068 /*
1069 * when adding the first or removing the last GEM/TKIP interface,
1070 * we have to adjust the number of spare blocks.
1071 */
1072 change_spare = (key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1073 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP) &&
1074 ((priv->extra_spare_vif_count == 0 && cmd == SET_KEY) ||
1075 (priv->extra_spare_vif_count == 1 && cmd == DISABLE_KEY));
1076
1077 /* no need to change spare - just regular set_key */
1078 if (!change_spare)
1079 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1080
1081 /*
1082 * stop the queues and flush to ensure the next packets are
1083 * in sync with FW spare block accounting
1084 */
1085 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
1086 wl1271_tx_flush(wl);
1087
1088 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1089 if (ret < 0)
1090 goto out;
1091
1092 /* key is now set, change the spare blocks */
1093 if (cmd == SET_KEY) {
1094 ret = wl18xx_set_host_cfg_bitmap(wl,
1095 WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1096 if (ret < 0)
1097 goto out;
1098
1099 priv->extra_spare_vif_count++;
1100 } else {
1101 ret = wl18xx_set_host_cfg_bitmap(wl,
1102 WL18XX_TX_HW_BLOCK_SPARE);
1103 if (ret < 0)
1104 goto out;
1105
1106 priv->extra_spare_vif_count--;
1107 }
1108
1109out:
1110 wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
1111 return ret;
1041} 1112}
1042 1113
1043static struct wlcore_ops wl18xx_ops = { 1114static struct wlcore_ops wl18xx_ops = {
@@ -1063,6 +1134,7 @@ static struct wlcore_ops wl18xx_ops = {
1063 .debugfs_init = wl18xx_debugfs_add_files, 1134 .debugfs_init = wl18xx_debugfs_add_files,
1064 .handle_static_data = wl18xx_handle_static_data, 1135 .handle_static_data = wl18xx_handle_static_data,
1065 .get_spare_blocks = wl18xx_get_spare_blocks, 1136 .get_spare_blocks = wl18xx_get_spare_blocks,
1137 .set_key = wl18xx_set_key,
1066}; 1138};
1067 1139
1068/* HT cap appropriate for wide channels */ 1140/* HT cap appropriate for wide channels */
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index 34e202bc2bb3..b9c43097d2f6 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -36,6 +36,9 @@ struct wl18xx_priv {
36 u8 last_fw_rls_idx; 36 u8 last_fw_rls_idx;
37 37
38 u8 board_type; 38 u8 board_type;
39
40 /* number of VIFs requiring extra spare mem-blocks */
41 int extra_spare_vif_count;
39}; 42};
40 43
41#define WL18XX_FW_MAX_TX_STATUS_DESC 33 44#define WL18XX_FW_MAX_TX_STATUS_DESC 33
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index 2cb35218ba47..34e0498727fc 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -176,4 +176,16 @@ wlcore_hw_get_spare_blocks(struct wl1271 *wl, bool is_gem)
176 return wl->ops->get_spare_blocks(wl, is_gem); 176 return wl->ops->get_spare_blocks(wl, is_gem);
177} 177}
178 178
179static inline int
180wlcore_hw_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
181 struct ieee80211_vif *vif,
182 struct ieee80211_sta *sta,
183 struct ieee80211_key_conf *key_conf)
184{
185 if (!wl->ops->set_key)
186 BUG_ON(1);
187
188 return wl->ops->set_key(wl, cmd, vif, sta, key_conf);
189}
190
179#endif 191#endif
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index d81c86cbbf71..7c4f78136bb1 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2883,12 +2883,21 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2883 return 0; 2883 return 0;
2884} 2884}
2885 2885
2886static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 2886static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2887 struct ieee80211_vif *vif, 2887 struct ieee80211_vif *vif,
2888 struct ieee80211_sta *sta, 2888 struct ieee80211_sta *sta,
2889 struct ieee80211_key_conf *key_conf) 2889 struct ieee80211_key_conf *key_conf)
2890{ 2890{
2891 struct wl1271 *wl = hw->priv; 2891 struct wl1271 *wl = hw->priv;
2892
2893 return wlcore_hw_set_key(wl, cmd, vif, sta, key_conf);
2894}
2895
2896int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
2897 struct ieee80211_vif *vif,
2898 struct ieee80211_sta *sta,
2899 struct ieee80211_key_conf *key_conf)
2900{
2892 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 2901 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
2893 int ret; 2902 int ret;
2894 u32 tx_seq_32 = 0; 2903 u32 tx_seq_32 = 0;
@@ -2999,6 +3008,7 @@ out_unlock:
2999 3008
3000 return ret; 3009 return ret;
3001} 3010}
3011EXPORT_SYMBOL_GPL(wlcore_set_key);
3002 3012
3003static int wl1271_op_hw_scan(struct ieee80211_hw *hw, 3013static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3004 struct ieee80211_vif *vif, 3014 struct ieee80211_vif *vif,
@@ -4643,7 +4653,7 @@ static const struct ieee80211_ops wl1271_ops = {
4643 .prepare_multicast = wl1271_op_prepare_multicast, 4653 .prepare_multicast = wl1271_op_prepare_multicast,
4644 .configure_filter = wl1271_op_configure_filter, 4654 .configure_filter = wl1271_op_configure_filter,
4645 .tx = wl1271_op_tx, 4655 .tx = wl1271_op_tx,
4646 .set_key = wl1271_op_set_key, 4656 .set_key = wlcore_op_set_key,
4647 .hw_scan = wl1271_op_hw_scan, 4657 .hw_scan = wl1271_op_hw_scan,
4648 .cancel_hw_scan = wl1271_op_cancel_hw_scan, 4658 .cancel_hw_scan = wl1271_op_cancel_hw_scan,
4649 .sched_scan_start = wl1271_op_sched_scan_start, 4659 .sched_scan_start = wl1271_op_sched_scan_start,
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 78bf1b9208a9..da9a07d2cf4b 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -1055,6 +1055,7 @@ out:
1055 wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); 1055 wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH);
1056 mutex_unlock(&wl->flush_mutex); 1056 mutex_unlock(&wl->flush_mutex);
1057} 1057}
1058EXPORT_SYMBOL_GPL(wl1271_tx_flush);
1058 1059
1059u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) 1060u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set)
1060{ 1061{
@@ -1115,6 +1116,7 @@ void wlcore_stop_queues(struct wl1271 *wl,
1115 for (i = 0; i < NUM_TX_QUEUES; i++) 1116 for (i = 0; i < NUM_TX_QUEUES; i++)
1116 wlcore_stop_queue(wl, i, reason); 1117 wlcore_stop_queue(wl, i, reason);
1117} 1118}
1119EXPORT_SYMBOL_GPL(wlcore_stop_queues);
1118 1120
1119void wlcore_wake_queues(struct wl1271 *wl, 1121void wlcore_wake_queues(struct wl1271 *wl,
1120 enum wlcore_queue_stop_reason reason) 1122 enum wlcore_queue_stop_reason reason)
@@ -1124,6 +1126,7 @@ void wlcore_wake_queues(struct wl1271 *wl,
1124 for (i = 0; i < NUM_TX_QUEUES; i++) 1126 for (i = 0; i < NUM_TX_QUEUES; i++)
1125 wlcore_wake_queue(wl, i, reason); 1127 wlcore_wake_queue(wl, i, reason);
1126} 1128}
1129EXPORT_SYMBOL_GPL(wlcore_wake_queues);
1127 1130
1128void wlcore_reset_stopped_queues(struct wl1271 *wl) 1131void wlcore_reset_stopped_queues(struct wl1271 *wl)
1129{ 1132{
diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index e058a55f533d..49e441f34839 100644
--- a/drivers/net/wireless/ti/wlcore/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -188,6 +188,7 @@ enum wlcore_queue_stop_reason {
188 WLCORE_QUEUE_STOP_REASON_WATERMARK, 188 WLCORE_QUEUE_STOP_REASON_WATERMARK,
189 WLCORE_QUEUE_STOP_REASON_FW_RESTART, 189 WLCORE_QUEUE_STOP_REASON_FW_RESTART,
190 WLCORE_QUEUE_STOP_REASON_FLUSH, 190 WLCORE_QUEUE_STOP_REASON_FLUSH,
191 WLCORE_QUEUE_STOP_REASON_SPARE_BLK, /* 18xx specific */
191}; 192};
192 193
193static inline int wl1271_tx_get_queue(int queue) 194static inline int wl1271_tx_get_queue(int queue)
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 99a061950a3a..4ca968fac0eb 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -76,6 +76,10 @@ struct wlcore_ops {
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 int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem);
79 int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd,
80 struct ieee80211_vif *vif,
81 struct ieee80211_sta *sta,
82 struct ieee80211_key_conf *key_conf);
79}; 83};
80 84
81enum wlcore_partitions { 85enum wlcore_partitions {
@@ -387,6 +391,10 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
387int __devexit wlcore_remove(struct platform_device *pdev); 391int __devexit wlcore_remove(struct platform_device *pdev);
388struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size); 392struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size);
389int wlcore_free_hw(struct wl1271 *wl); 393int wlcore_free_hw(struct wl1271 *wl);
394int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
395 struct ieee80211_vif *vif,
396 struct ieee80211_sta *sta,
397 struct ieee80211_key_conf *key_conf);
390 398
391/* Firmware image load chunk size */ 399/* Firmware image load chunk size */
392#define CHUNK_SIZE 16384 400#define CHUNK_SIZE 16384