aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-08-14 06:17:05 -0400
committerLuciano Coelho <coelho@ti.com>2011-08-22 05:35:23 -0400
commit4d56ad9cae9e8553176427adc2335f8a7f4556b2 (patch)
treea3e86714bc8b8136e72c963a1a00815ad7bf5a46 /drivers/net/wireless/wl12xx
parent08c1d1c7042330e2280a7718be4ad88c2e8f8268 (diff)
wl12xx: update fw status struct
Update the fw status struct according to the new fw api (fw >= 6/7.0.0.35). All the roles use the same struct now. The memory accounting was changed a bit according to the struct changes. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c5
-rw-r--r--drivers/net/wireless/wl12xx/main.c82
-rw-r--r--drivers/net/wireless/wl12xx/rx.c18
-rw-r--r--drivers/net/wireless/wl12xx/rx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h55
5 files changed, 68 insertions, 94 deletions
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index fd1c301be7c7..3102652c7625 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -349,10 +349,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
349 DRIVER_STATE_PRINT_INT(tx_packets_count); 349 DRIVER_STATE_PRINT_INT(tx_packets_count);
350 DRIVER_STATE_PRINT_INT(tx_results_count); 350 DRIVER_STATE_PRINT_INT(tx_results_count);
351 DRIVER_STATE_PRINT_LHEX(flags); 351 DRIVER_STATE_PRINT_LHEX(flags);
352 DRIVER_STATE_PRINT_INT(tx_blocks_freed[0]); 352 DRIVER_STATE_PRINT_INT(tx_blocks_freed);
353 DRIVER_STATE_PRINT_INT(tx_blocks_freed[1]);
354 DRIVER_STATE_PRINT_INT(tx_blocks_freed[2]);
355 DRIVER_STATE_PRINT_INT(tx_blocks_freed[3]);
356 DRIVER_STATE_PRINT_INT(tx_security_last_seq_lsb); 353 DRIVER_STATE_PRINT_INT(tx_security_last_seq_lsb);
357 DRIVER_STATE_PRINT_INT(rx_counter); 354 DRIVER_STATE_PRINT_INT(rx_counter);
358 DRIVER_STATE_PRINT_INT(session_counter); 355 DRIVER_STATE_PRINT_INT(session_counter);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 7fcdfa3ee1db..96f76b104e75 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -826,22 +826,14 @@ static void wl1271_irq_update_links_status(struct wl1271 *wl,
826} 826}
827#endif 827#endif
828 828
829static void wl1271_fw_status(struct wl1271 *wl, 829static void wl12xx_fw_status(struct wl1271 *wl,
830 struct wl1271_fw_full_status *full_status) 830 struct wl12xx_fw_status *status)
831{ 831{
832 struct wl1271_fw_common_status *status = &full_status->common;
833 struct timespec ts; 832 struct timespec ts;
834 u32 old_tx_blk_count = wl->tx_blocks_available; 833 u32 old_tx_blk_count = wl->tx_blocks_available;
835 u32 freed_blocks = 0; 834 int avail, freed_blocks;
836 int i;
837 835
838 if (wl->bss_type == BSS_TYPE_AP_BSS) { 836 wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
839 wl1271_raw_read(wl, FW_STATUS_ADDR, status,
840 sizeof(struct wl1271_fw_ap_status), false);
841 } else {
842 wl1271_raw_read(wl, FW_STATUS_ADDR, status,
843 sizeof(struct wl1271_fw_sta_status), false);
844 }
845 837
846 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " 838 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
847 "drv_rx_counter = %d, tx_results_counter = %d)", 839 "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -850,42 +842,36 @@ static void wl1271_fw_status(struct wl1271 *wl,
850 status->drv_rx_counter, 842 status->drv_rx_counter,
851 status->tx_results_counter); 843 status->tx_results_counter);
852 844
853 /* update number of available TX blocks */ 845 freed_blocks = le32_to_cpu(status->total_released_blks) -
854 for (i = 0; i < NUM_TX_QUEUES; i++) { 846 wl->tx_blocks_freed;
855 freed_blocks += le32_to_cpu(status->tx_released_blks[i]) - 847 wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks);
856 wl->tx_blocks_freed[i];
857
858 wl->tx_blocks_freed[i] =
859 le32_to_cpu(status->tx_released_blks[i]);
860 }
861 848
862 wl->tx_allocated_blocks -= freed_blocks; 849 wl->tx_allocated_blocks -= freed_blocks;
863 850
864 if (wl->bss_type == BSS_TYPE_AP_BSS) { 851 avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks;
865 /* Update num of allocated TX blocks per link and ps status */
866#if 0
867 wl1271_irq_update_links_status(wl, &full_status->ap);
868#endif
869 wl->tx_blocks_available += freed_blocks;
870 } else {
871 int avail = full_status->sta.tx_total - wl->tx_allocated_blocks;
872 852
873 /* 853 /*
874 * The FW might change the total number of TX memblocks before 854 * The FW might change the total number of TX memblocks before
875 * we get a notification about blocks being released. Thus, the 855 * we get a notification about blocks being released. Thus, the
876 * available blocks calculation might yield a temporary result 856 * available blocks calculation might yield a temporary result
877 * which is lower than the actual available blocks. Keeping in 857 * which is lower than the actual available blocks. Keeping in
878 * mind that only blocks that were allocated can be moved from 858 * mind that only blocks that were allocated can be moved from
879 * TX to RX, tx_blocks_available should never decrease here. 859 * TX to RX, tx_blocks_available should never decrease here.
880 */ 860 */
881 wl->tx_blocks_available = max((int)wl->tx_blocks_available, 861 wl->tx_blocks_available = max((int)wl->tx_blocks_available,
882 avail); 862 avail);
883 }
884 863
885 /* if more blocks are available now, tx work can be scheduled */ 864 /* if more blocks are available now, tx work can be scheduled */
886 if (wl->tx_blocks_available > old_tx_blk_count) 865 if (wl->tx_blocks_available > old_tx_blk_count)
887 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); 866 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
888 867
868 /* for AP update num of allocated TX blocks per link and ps status */
869 if (wl->bss_type == BSS_TYPE_AP_BSS) {
870#if 0
871 wl1271_irq_update_links_status(wl, status);
872#endif
873 }
874
889 /* update the host-chipset time offset */ 875 /* update the host-chipset time offset */
890 getnstimeofday(&ts); 876 getnstimeofday(&ts);
891 wl->time_offset = (timespec_to_ns(&ts) >> 10) - 877 wl->time_offset = (timespec_to_ns(&ts) >> 10) -
@@ -958,8 +944,8 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
958 clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); 944 clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
959 smp_mb__after_clear_bit(); 945 smp_mb__after_clear_bit();
960 946
961 wl1271_fw_status(wl, wl->fw_status); 947 wl12xx_fw_status(wl, wl->fw_status);
962 intr = le32_to_cpu(wl->fw_status->common.intr); 948 intr = le32_to_cpu(wl->fw_status->intr);
963 intr &= WL1271_INTR_MASK; 949 intr &= WL1271_INTR_MASK;
964 if (!intr) { 950 if (!intr) {
965 done = true; 951 done = true;
@@ -978,7 +964,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
978 if (likely(intr & WL1271_ACX_INTR_DATA)) { 964 if (likely(intr & WL1271_ACX_INTR_DATA)) {
979 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); 965 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
980 966
981 wl1271_rx(wl, &wl->fw_status->common); 967 wl12xx_rx(wl, wl->fw_status);
982 968
983 /* Check if any tx blocks were freed */ 969 /* Check if any tx blocks were freed */
984 spin_lock_irqsave(&wl->wl_lock, flags); 970 spin_lock_irqsave(&wl->wl_lock, flags);
@@ -995,7 +981,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
995 } 981 }
996 982
997 /* check for tx results */ 983 /* check for tx results */
998 if (wl->fw_status->common.tx_results_counter != 984 if (wl->fw_status->tx_results_counter !=
999 (wl->tx_results_count & 0xff)) 985 (wl->tx_results_count & 0xff))
1000 wl1271_tx_complete(wl); 986 wl1271_tx_complete(wl);
1001 987
@@ -1169,8 +1155,8 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
1169 wl12xx_cmd_stop_fwlog(wl); 1155 wl12xx_cmd_stop_fwlog(wl);
1170 1156
1171 /* Read the first memory block address */ 1157 /* Read the first memory block address */
1172 wl1271_fw_status(wl, wl->fw_status); 1158 wl12xx_fw_status(wl, wl->fw_status);
1173 first_addr = __le32_to_cpu(wl->fw_status->sta.log_start_addr); 1159 first_addr = le32_to_cpu(wl->fw_status->log_start_addr);
1174 if (!first_addr) 1160 if (!first_addr)
1175 goto out; 1161 goto out;
1176 1162
@@ -1186,7 +1172,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
1186 * of each memory block hold the hardware address of the next 1172 * of each memory block hold the hardware address of the next
1187 * one. The last memory block points to the first one. 1173 * one. The last memory block points to the first one.
1188 */ 1174 */
1189 addr = __le32_to_cpup((__le32 *)block); 1175 addr = le32_to_cpup((__le32 *)block);
1190 if (!wl12xx_copy_fwlog(wl, block + sizeof(addr), 1176 if (!wl12xx_copy_fwlog(wl, block + sizeof(addr),
1191 WL12XX_HW_BLOCK_SIZE - sizeof(addr))) 1177 WL12XX_HW_BLOCK_SIZE - sizeof(addr)))
1192 break; 1178 break;
@@ -1923,7 +1909,6 @@ out:
1923static void __wl1271_op_remove_interface(struct wl1271 *wl, 1909static void __wl1271_op_remove_interface(struct wl1271 *wl,
1924 bool reset_tx_queues) 1910 bool reset_tx_queues)
1925{ 1911{
1926 int i;
1927 1912
1928 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); 1913 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
1929 1914
@@ -2004,8 +1989,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2004 */ 1989 */
2005 wl->flags = 0; 1990 wl->flags = 0;
2006 1991
2007 for (i = 0; i < NUM_TX_QUEUES; i++) 1992 wl->tx_blocks_freed = 0;
2008 wl->tx_blocks_freed[i] = 0;
2009 1993
2010 wl1271_debugfs_reset(wl); 1994 wl1271_debugfs_reset(wl);
2011 1995
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 7a0c5fe294b2..78d8410da1f4 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -30,21 +30,21 @@
30#include "rx.h" 30#include "rx.h"
31#include "io.h" 31#include "io.h"
32 32
33static u8 wl1271_rx_get_mem_block(struct wl1271_fw_common_status *status, 33static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status,
34 u32 drv_rx_counter) 34 u32 drv_rx_counter)
35{ 35{
36 return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & 36 return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
37 RX_MEM_BLOCK_MASK; 37 RX_MEM_BLOCK_MASK;
38} 38}
39 39
40static u32 wl1271_rx_get_buf_size(struct wl1271_fw_common_status *status, 40static u32 wl12xx_rx_get_buf_size(struct wl12xx_fw_status *status,
41 u32 drv_rx_counter) 41 u32 drv_rx_counter)
42{ 42{
43 return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & 43 return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
44 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; 44 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
45} 45}
46 46
47static bool wl1271_rx_get_unaligned(struct wl1271_fw_common_status *status, 47static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status,
48 u32 drv_rx_counter) 48 u32 drv_rx_counter)
49{ 49{
50 /* Convert the value to bool */ 50 /* Convert the value to bool */
@@ -181,7 +181,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
181 return is_data; 181 return is_data;
182} 182}
183 183
184void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) 184void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
185{ 185{
186 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; 186 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
187 u32 buf_size; 187 u32 buf_size;
@@ -199,7 +199,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
199 buf_size = 0; 199 buf_size = 0;
200 rx_counter = drv_rx_counter; 200 rx_counter = drv_rx_counter;
201 while (rx_counter != fw_rx_counter) { 201 while (rx_counter != fw_rx_counter) {
202 pkt_length = wl1271_rx_get_buf_size(status, rx_counter); 202 pkt_length = wl12xx_rx_get_buf_size(status, rx_counter);
203 if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE) 203 if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE)
204 break; 204 break;
205 buf_size += pkt_length; 205 buf_size += pkt_length;
@@ -218,7 +218,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
218 * For aggregated packets, only the first memory block 218 * For aggregated packets, only the first memory block
219 * should be retrieved. The FW takes care of the rest. 219 * should be retrieved. The FW takes care of the rest.
220 */ 220 */
221 mem_block = wl1271_rx_get_mem_block(status, 221 mem_block = wl12xx_rx_get_mem_block(status,
222 drv_rx_counter); 222 drv_rx_counter);
223 223
224 wl->rx_mem_pool_addr.addr = (mem_block << 8) + 224 wl->rx_mem_pool_addr.addr = (mem_block << 8) +
@@ -239,10 +239,10 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
239 /* Split data into separate packets */ 239 /* Split data into separate packets */
240 pkt_offset = 0; 240 pkt_offset = 0;
241 while (pkt_offset < buf_size) { 241 while (pkt_offset < buf_size) {
242 pkt_length = wl1271_rx_get_buf_size(status, 242 pkt_length = wl12xx_rx_get_buf_size(status,
243 drv_rx_counter); 243 drv_rx_counter);
244 244
245 unaligned = wl1271_rx_get_unaligned(status, 245 unaligned = wl12xx_rx_get_unaligned(status,
246 drv_rx_counter); 246 drv_rx_counter);
247 247
248 /* 248 /*
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
index d3c0591665e8..00c1c1d27aaa 100644
--- a/drivers/net/wireless/wl12xx/rx.h
+++ b/drivers/net/wireless/wl12xx/rx.h
@@ -129,7 +129,7 @@ struct wl1271_rx_descriptor {
129 u8 reserved; 129 u8 reserved;
130} __packed; 130} __packed;
131 131
132void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status); 132void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status);
133u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 133u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
134 134
135#endif 135#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 7707895120be..f708cd70185a 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -137,6 +137,7 @@ extern u32 wl12xx_debug_level;
137#define WL1271_DEFAULT_BEACON_INT 100 137#define WL1271_DEFAULT_BEACON_INT 100
138#define WL1271_DEFAULT_DTIM_PERIOD 1 138#define WL1271_DEFAULT_DTIM_PERIOD 1
139 139
140#define WL12XX_MAX_LINKS 8
140#define WL1271_AP_GLOBAL_HLID 0 141#define WL1271_AP_GLOBAL_HLID 0
141#define WL1271_AP_BROADCAST_HLID 1 142#define WL1271_AP_BROADCAST_HLID 1
142#define WL1271_AP_STA_HLID_START 2 143#define WL1271_AP_STA_HLID_START 2
@@ -230,23 +231,15 @@ struct wl1271_stats {
230/* Broadcast and Global links + links to stations */ 231/* Broadcast and Global links + links to stations */
231#define AP_MAX_LINKS (AP_MAX_STATIONS + 2) 232#define AP_MAX_LINKS (AP_MAX_STATIONS + 2)
232 233
233/* FW status registers common for AP/STA */ 234/* FW status registers */
234struct wl1271_fw_common_status { 235struct wl12xx_fw_status {
235 __le32 intr; 236 __le32 intr;
236 u8 fw_rx_counter; 237 u8 fw_rx_counter;
237 u8 drv_rx_counter; 238 u8 drv_rx_counter;
238 u8 reserved; 239 u8 reserved;
239 u8 tx_results_counter; 240 u8 tx_results_counter;
240 __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; 241 __le32 rx_pkt_descs[NUM_RX_PKT_DESC];
241 __le32 tx_released_blks[NUM_TX_QUEUES];
242 __le32 fw_localtime; 242 __le32 fw_localtime;
243} __packed;
244
245/* FW status registers for AP */
246struct wl1271_fw_ap_status {
247 struct wl1271_fw_common_status common;
248
249 /* Next fields valid only in AP FW */
250 243
251 /* 244 /*
252 * A bitmap (where each bit represents a single HLID) 245 * A bitmap (where each bit represents a single HLID)
@@ -254,29 +247,29 @@ struct wl1271_fw_ap_status {
254 */ 247 */
255 __le32 link_ps_bitmap; 248 __le32 link_ps_bitmap;
256 249
257 /* Number of freed MBs per HLID */ 250 /*
258 u8 tx_lnk_free_blks[AP_MAX_LINKS]; 251 * A bitmap (where each bit represents a single HLID) to indicate
259 u8 padding_1[1]; 252 * if the station is in Fast mode
260} __packed; 253 */
254 __le32 link_fast_bitmap;
261 255
262/* FW status registers for STA */ 256 /* Cumulative counter of total released mem blocks since FW-reset */
263struct wl1271_fw_sta_status { 257 __le32 total_released_blks;
264 struct wl1271_fw_common_status common;
265 258
266 u8 tx_total; 259 /* Size (in Memory Blocks) of TX pool */
267 u8 reserved1; 260 __le32 tx_total;
268 __le16 reserved2;
269 __le32 log_start_addr;
270} __packed;
271 261
272struct wl1271_fw_full_status { 262 /* Cumulative counter of released mem-blocks per AC */
273 union { 263 u8 tx_released_blks[NUM_TX_QUEUES];
274 struct wl1271_fw_common_status common;
275 struct wl1271_fw_sta_status sta;
276 struct wl1271_fw_ap_status ap;
277 };
278} __packed;
279 264
265 /* Cumulative counter of freed MBs per HLID */
266 u8 tx_lnk_free_blks[WL12XX_MAX_LINKS];
267
268 /* Cumulative counter of released Voice memory blocks */
269 u8 tx_voice_released_blks;
270 u8 padding_1[7];
271 __le32 log_start_addr;
272} __packed;
280 273
281struct wl1271_rx_mem_pool_addr { 274struct wl1271_rx_mem_pool_addr {
282 u32 addr; 275 u32 addr;
@@ -401,7 +394,7 @@ struct wl1271 {
401 struct wl1271_acx_mem_map *target_mem_map; 394 struct wl1271_acx_mem_map *target_mem_map;
402 395
403 /* Accounting for allocated / available TX blocks on HW */ 396 /* Accounting for allocated / available TX blocks on HW */
404 u32 tx_blocks_freed[NUM_TX_QUEUES]; 397 u32 tx_blocks_freed;
405 u32 tx_blocks_available; 398 u32 tx_blocks_available;
406 u32 tx_allocated_blocks; 399 u32 tx_allocated_blocks;
407 u32 tx_results_count; 400 u32 tx_results_count;
@@ -537,7 +530,7 @@ struct wl1271 {
537 u32 buffer_cmd; 530 u32 buffer_cmd;
538 u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; 531 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
539 532
540 struct wl1271_fw_full_status *fw_status; 533 struct wl12xx_fw_status *fw_status;
541 struct wl1271_tx_hw_res_if *tx_res_if; 534 struct wl1271_tx_hw_res_if *tx_res_if;
542 535
543 struct ieee80211_vif *vif; 536 struct ieee80211_vif *vif;