2 * This file is part of wl1271
4 * Copyright (C) 2009 Nokia Corporation
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 #include <linux/kernel.h>
25 #include <linux/module.h>
28 #include "wl1271_spi.h"
29 #include "wl1271_reg.h"
30 #include "wl1271_ps.h"
31 #include "wl1271_tx.h"
33 static int wl1271_tx_id(struct wl1271
*wl
, struct sk_buff
*skb
)
37 for (i
= 0; i
< FW_TX_CMPLT_BLOCK_SIZE
; i
++)
38 if (wl
->tx_frames
[i
] == NULL
) {
39 wl
->tx_frames
[i
] = skb
;
46 static int wl1271_tx_allocate(struct wl1271
*wl
, struct sk_buff
*skb
, u32 extra
)
48 struct wl1271_tx_hw_descr
*desc
;
49 u32 total_len
= skb
->len
+ sizeof(struct wl1271_tx_hw_descr
) + extra
;
50 u32 total_blocks
, excluded
;
53 /* allocate free identifier for the packet */
54 id
= wl1271_tx_id(wl
, skb
);
58 /* approximate the number of blocks required for this packet
60 /* FIXME: try to figure out what is done here and make it cleaner */
61 total_blocks
= (skb
->len
) >> TX_HW_BLOCK_SHIFT_DIV
;
62 excluded
= (total_blocks
<< 2) + (skb
->len
& 0xff) + 34;
63 total_blocks
+= (excluded
> 252) ? 2 : 1;
64 total_blocks
+= TX_HW_BLOCK_SPARE
;
66 if (total_blocks
<= wl
->tx_blocks_available
) {
67 desc
= (struct wl1271_tx_hw_descr
*)skb_push(
68 skb
, total_len
- skb
->len
);
70 desc
->extra_mem_blocks
= TX_HW_BLOCK_SPARE
;
71 desc
->total_mem_blocks
= total_blocks
;
74 wl
->tx_blocks_available
-= total_blocks
;
78 wl1271_debug(DEBUG_TX
,
79 "tx_allocate: size: %d, blocks: %d, id: %d",
80 total_len
, total_blocks
, id
);
82 wl
->tx_frames
[id
] = NULL
;
87 static int wl1271_tx_fill_hdr(struct wl1271
*wl
, struct sk_buff
*skb
,
88 u32 extra
, struct ieee80211_tx_info
*control
)
90 struct wl1271_tx_hw_descr
*desc
;
93 desc
= (struct wl1271_tx_hw_descr
*) skb
->data
;
95 /* configure packet life time */
96 desc
->start_time
= jiffies_to_usecs(jiffies
) - wl
->time_offset
;
97 desc
->life_time
= TX_HW_MGMT_PKT_LIFETIME_TU
;
99 /* configure the tx attributes */
100 desc
->tx_attr
= wl
->session_counter
<< TX_HW_ATTR_OFST_SESSION_COUNTER
;
101 /* FIXME: do we know the packet priority? can we identify mgmt
102 packets, and use max prio for them at least? */
104 desc
->aid
= TX_HW_DEFAULT_AID
;
107 /* align the length (and store in terms of words) */
108 pad
= WL1271_TX_ALIGN(skb
->len
);
109 desc
->length
= pad
>> 2;
111 /* calculate number of padding bytes */
112 pad
= pad
- skb
->len
;
113 desc
->tx_attr
|= pad
<< TX_HW_ATTR_OFST_LAST_WORD_PAD
;
115 wl1271_debug(DEBUG_TX
, "tx_fill_hdr: pad: %d", pad
);
119 static int wl1271_tx_send_packet(struct wl1271
*wl
, struct sk_buff
*skb
,
120 struct ieee80211_tx_info
*control
)
123 struct wl1271_tx_hw_descr
*desc
;
126 /* FIXME: This is a workaround for getting non-aligned packets.
127 This happens at least with EAPOL packets from the user space.
128 Our DMA requires packets to be aligned on a 4-byte boundary.
130 if (unlikely((long)skb
->data
& 0x03)) {
131 int offset
= (4 - (long)skb
->data
) & 0x03;
132 wl1271_debug(DEBUG_TX
, "skb offset %d", offset
);
134 /* check whether the current skb can be used */
135 if (!skb_cloned(skb
) && (skb_tailroom(skb
) >= offset
)) {
136 unsigned char *src
= skb
->data
;
138 /* align the buffer on a 4-byte boundary */
139 skb_reserve(skb
, offset
);
140 memmove(skb
->data
, src
, skb
->len
);
142 wl1271_info("No handler, fixme!");
147 len
= WL1271_TX_ALIGN(skb
->len
);
149 /* perform a fixed address block write with the packet */
150 wl1271_spi_reg_write(wl
, WL1271_SLV_MEM_DATA
, skb
->data
, len
, true);
152 /* write packet new counter into the write access register */
153 wl
->tx_packets_count
++;
154 wl1271_reg_write32(wl
, WL1271_HOST_WR_ACCESS
, wl
->tx_packets_count
);
156 desc
= (struct wl1271_tx_hw_descr
*) skb
->data
;
157 wl1271_debug(DEBUG_TX
, "tx id %u skb 0x%p payload %u (%u words)",
158 desc
->id
, skb
, len
, desc
->length
);
163 /* caller must hold wl->mutex */
164 static int wl1271_tx_frame(struct wl1271
*wl
, struct sk_buff
*skb
)
166 struct ieee80211_tx_info
*info
;
174 info
= IEEE80211_SKB_CB(skb
);
176 if (info
->control
.hw_key
&&
177 info
->control
.hw_key
->alg
== ALG_TKIP
)
178 extra
= WL1271_TKIP_IV_SPACE
;
180 if (info
->control
.hw_key
) {
181 idx
= info
->control
.hw_key
->hw_key_idx
;
183 /* FIXME: do we have to do this if we're not using WEP? */
184 if (unlikely(wl
->default_key
!= idx
)) {
185 ret
= wl1271_cmd_set_default_wep_key(wl
, idx
);
191 ret
= wl1271_tx_allocate(wl
, skb
, extra
);
195 ret
= wl1271_tx_fill_hdr(wl
, skb
, extra
, info
);
199 ret
= wl1271_tx_send_packet(wl
, skb
, info
);
206 void wl1271_tx_work(struct work_struct
*work
)
208 struct wl1271
*wl
= container_of(work
, struct wl1271
, tx_work
);
210 bool woken_up
= false;
213 mutex_lock(&wl
->mutex
);
215 if (unlikely(wl
->state
== WL1271_STATE_OFF
))
218 while ((skb
= skb_dequeue(&wl
->tx_queue
))) {
220 ret
= wl1271_ps_elp_wakeup(wl
, false);
226 ret
= wl1271_tx_frame(wl
, skb
);
228 /* firmware buffer is full, stop queues */
229 wl1271_debug(DEBUG_TX
, "tx_work: fw buffer full, "
231 ieee80211_stop_queues(wl
->hw
);
232 wl
->tx_queue_stopped
= true;
233 skb_queue_head(&wl
->tx_queue
, skb
);
235 } else if (ret
< 0) {
238 } else if (wl
->tx_queue_stopped
) {
239 /* firmware buffer has space, restart queues */
240 wl1271_debug(DEBUG_TX
,
241 "complete_packet: waking queues");
242 ieee80211_wake_queues(wl
->hw
);
243 wl
->tx_queue_stopped
= false;
249 wl1271_ps_elp_sleep(wl
);
251 mutex_unlock(&wl
->mutex
);
254 static void wl1271_tx_complete_packet(struct wl1271
*wl
,
255 struct wl1271_tx_hw_res_descr
*result
)
258 struct ieee80211_tx_info
*info
;
263 /* check for id legality */
264 if (id
>= TX_HW_RESULT_QUEUE_LEN
|| wl
->tx_frames
[id
] == NULL
) {
265 wl1271_warning("TX result illegal id: %d", id
);
269 skb
= wl
->tx_frames
[id
];
270 info
= IEEE80211_SKB_CB(skb
);
272 /* update packet status */
273 if (!(info
->flags
& IEEE80211_TX_CTL_NO_ACK
)) {
274 if (result
->status
== TX_SUCCESS
)
275 info
->flags
|= IEEE80211_TX_STAT_ACK
;
276 if (result
->status
& TX_RETRY_EXCEEDED
) {
278 /* info->status.excessive_retries = 1; */
279 wl
->stats
.excessive_retries
++;
284 /* info->status.retry_count = result->ack_failures; */
285 wl
->stats
.retry_count
+= result
->ack_failures
;
288 if (info
->control
.hw_key
&&
289 info
->control
.hw_key
->alg
== ALG_TKIP
)
290 header_len
= WL1271_TKIP_IV_SPACE
+
291 sizeof(struct wl1271_tx_hw_descr
);
293 header_len
= sizeof(struct wl1271_tx_hw_descr
);
295 wl1271_debug(DEBUG_TX
, "tx status id %u skb 0x%p failures %u rate 0x%x"
297 result
->id
, skb
, result
->ack_failures
,
298 result
->rate_class_index
, result
->status
);
300 /* remove private header from packet */
301 skb_pull(skb
, header_len
);
303 /* return the packet to the stack */
304 ieee80211_tx_status(wl
->hw
, skb
);
305 wl
->tx_frames
[result
->id
] = NULL
;
308 /* Called upon reception of a TX complete interrupt */
309 void wl1271_tx_complete(struct wl1271
*wl
, u32 count
)
311 struct wl1271_acx_mem_map
*memmap
=
312 (struct wl1271_acx_mem_map
*)wl
->target_mem_map
;
315 wl1271_debug(DEBUG_TX
, "tx_complete received, packets: %d", count
);
317 /* read the tx results from the chipset */
318 wl1271_spi_mem_read(wl
, memmap
->tx_result
,
319 wl
->tx_res_if
, sizeof(*wl
->tx_res_if
));
321 /* verify that the result buffer is not getting overrun */
322 if (count
> TX_HW_RESULT_QUEUE_LEN
) {
323 wl1271_warning("TX result overflow from chipset: %d", count
);
324 count
= TX_HW_RESULT_QUEUE_LEN
;
327 /* process the results */
328 for (i
= 0; i
< count
; i
++) {
329 struct wl1271_tx_hw_res_descr
*result
;
330 u8 offset
= wl
->tx_results_count
& TX_HW_RESULT_QUEUE_LEN_MASK
;
332 /* process the packet */
333 result
= &(wl
->tx_res_if
->tx_results_queue
[offset
]);
334 wl1271_tx_complete_packet(wl
, result
);
336 wl
->tx_results_count
++;
339 /* write host counter to chipset (to ack) */
340 wl1271_mem_write32(wl
, memmap
->tx_result
+
341 offsetof(struct wl1271_tx_hw_res_if
,
342 tx_result_host_counter
),
343 wl
->tx_res_if
->tx_result_fw_counter
);
346 /* caller must hold wl->mutex */
347 void wl1271_tx_flush(struct wl1271
*wl
)
351 struct ieee80211_tx_info
*info
;
354 /* control->flags = 0; FIXME */
356 while ((skb
= skb_dequeue(&wl
->tx_queue
))) {
357 info
= IEEE80211_SKB_CB(skb
);
359 wl1271_debug(DEBUG_TX
, "flushing skb 0x%p", skb
);
361 if (!(info
->flags
& IEEE80211_TX_CTL_REQ_TX_STATUS
))
364 ieee80211_tx_status(wl
->hw
, skb
);
367 for (i
= 0; i
< FW_TX_CMPLT_BLOCK_SIZE
; i
++)
368 if (wl
->tx_frames
[i
] != NULL
) {
369 skb
= wl
->tx_frames
[i
];
370 info
= IEEE80211_SKB_CB(skb
);
372 if (!(info
->flags
& IEEE80211_TX_CTL_REQ_TX_STATUS
))
375 ieee80211_tx_status(wl
->hw
, skb
);
376 wl
->tx_frames
[i
] = NULL
;