aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_rx.c
diff options
context:
space:
mode:
authorShahar Levi <shahar_levi@ti.com>2010-11-08 06:20:10 -0500
committerLuciano Coelho <luciano.coelho@nokia.com>2010-11-22 09:45:09 -0500
commit00d201001bd4e8a46e3d03c970abcb72256c368b (patch)
tree2d3d6b971c9e0ac68ffd5edca1c596eeab247451 /drivers/net/wireless/wl12xx/wl1271_rx.c
parenta76a574ca9ce7c05791cee42f000f2a42c687837 (diff)
wl1271: Change wl12xx Files Names
All files name prefix removed due to the fact that wl12xx driver supports wl1271 and wl1273. Also the definition in Kconfig and header files changed respectively. Signed-off-by: Shahar Levi <shahar_levi@ti.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_rx.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c203
1 files changed, 0 insertions, 203 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
deleted file mode 100644
index cacfee56a0d0..000000000000
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ /dev/null
@@ -1,203 +0,0 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
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.
11 *
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.
16 *
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
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/gfp.h>
25
26#include "wl1271.h"
27#include "wl1271_acx.h"
28#include "wl1271_reg.h"
29#include "wl1271_rx.h"
30#include "wl1271_io.h"
31
32static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
33 u32 drv_rx_counter)
34{
35 return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
36 RX_MEM_BLOCK_MASK;
37}
38
39static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status,
40 u32 drv_rx_counter)
41{
42 return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
43 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
44}
45
46static void wl1271_rx_status(struct wl1271 *wl,
47 struct wl1271_rx_descriptor *desc,
48 struct ieee80211_rx_status *status,
49 u8 beacon)
50{
51 enum ieee80211_band desc_band;
52
53 memset(status, 0, sizeof(struct ieee80211_rx_status));
54
55 status->band = wl->band;
56
57 if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
58 desc_band = IEEE80211_BAND_2GHZ;
59 else
60 desc_band = IEEE80211_BAND_5GHZ;
61
62 status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band);
63
64#ifdef CONFIG_WL1271_HT
65 /* 11n support */
66 if (desc->rate <= CONF_HW_RXTX_RATE_MCS0)
67 status->flag |= RX_FLAG_HT;
68#endif
69
70 status->signal = desc->rssi;
71
72 /*
73 * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we
74 * need to divide by two for now, but TI has been discussing about
75 * changing it. This needs to be rechecked.
76 */
77 wl->noise = desc->rssi - (desc->snr >> 1);
78
79 status->freq = ieee80211_channel_to_frequency(desc->channel);
80
81 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
82 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
83
84 if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL)))
85 status->flag |= RX_FLAG_DECRYPTED;
86 if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL))
87 status->flag |= RX_FLAG_MMIC_ERROR;
88 }
89}
90
91static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
92{
93 struct wl1271_rx_descriptor *desc;
94 struct sk_buff *skb;
95 u16 *fc;
96 u8 *buf;
97 u8 beacon = 0;
98
99 /*
100 * In PLT mode we seem to get frames and mac80211 warns about them,
101 * workaround this by not retrieving them at all.
102 */
103 if (unlikely(wl->state == WL1271_STATE_PLT))
104 return -EINVAL;
105
106 skb = __dev_alloc_skb(length, GFP_KERNEL);
107 if (!skb) {
108 wl1271_error("Couldn't allocate RX frame");
109 return -ENOMEM;
110 }
111
112 buf = skb_put(skb, length);
113 memcpy(buf, data, length);
114
115 /* the data read starts with the descriptor */
116 desc = (struct wl1271_rx_descriptor *) buf;
117
118 /* now we pull the descriptor out of the buffer */
119 skb_pull(skb, sizeof(*desc));
120
121 fc = (u16 *)skb->data;
122 if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
123 beacon = 1;
124
125 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
126
127 wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
128 beacon ? "beacon" : "");
129
130 skb_trim(skb, skb->len - desc->pad_len);
131
132 ieee80211_rx_ni(wl->hw, skb);
133
134 return 0;
135}
136
137void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
138{
139 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
140 u32 buf_size;
141 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
142 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
143 u32 rx_counter;
144 u32 mem_block;
145 u32 pkt_length;
146 u32 pkt_offset;
147
148 while (drv_rx_counter != fw_rx_counter) {
149 buf_size = 0;
150 rx_counter = drv_rx_counter;
151 while (rx_counter != fw_rx_counter) {
152 pkt_length = wl1271_rx_get_buf_size(status, rx_counter);
153 if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE)
154 break;
155 buf_size += pkt_length;
156 rx_counter++;
157 rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
158 }
159
160 if (buf_size == 0) {
161 wl1271_warning("received empty data");
162 break;
163 }
164
165 /*
166 * Choose the block we want to read
167 * For aggregated packets, only the first memory block should
168 * be retrieved. The FW takes care of the rest.
169 */
170 mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
171 wl->rx_mem_pool_addr.addr = (mem_block << 8) +
172 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
173 wl->rx_mem_pool_addr.addr_extra =
174 wl->rx_mem_pool_addr.addr + 4;
175 wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr,
176 sizeof(wl->rx_mem_pool_addr), false);
177
178 /* Read all available packets at once */
179 wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
180 buf_size, true);
181
182 /* Split data into separate packets */
183 pkt_offset = 0;
184 while (pkt_offset < buf_size) {
185 pkt_length = wl1271_rx_get_buf_size(status,
186 drv_rx_counter);
187 /*
188 * the handle data call can only fail in memory-outage
189 * conditions, in that case the received frame will just
190 * be dropped.
191 */
192 wl1271_rx_handle_data(wl,
193 wl->aggr_buf + pkt_offset,
194 pkt_length);
195 wl->rx_counter++;
196 drv_rx_counter++;
197 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
198 pkt_offset += pkt_length;
199 }
200 }
201 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS,
202 cpu_to_le32(wl->rx_counter));
203}