aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1251_rx.c
diff options
context:
space:
mode:
authorKalle Valo <kvalo@adurom.com>2010-10-10 04:28:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-11 15:04:23 -0400
commit9bc6772e15d25f58c1be638031280e04514287d4 (patch)
tree4cff1bcbeb40698df1bbdff7c06cd3a089bcc205 /drivers/net/wireless/wl12xx/wl1251_rx.c
parentf03ee1ec73d8cad07b0ef5ba6106a9fc4d179ecb (diff)
wl1251: move to it's own directory
wl1271 driver is under heavy development but on the other hand the older wl1251 driver is currently considered more as a legacy driver. To make it easier to develop wl1271 features move wl1251 to it's own directory, drivers/net/wireless/wl1251. There are no functional changes, only moving of files. One regression is that Kconfig won't be updated automatically and user needs to enable wl1251 manually with an older config file. Signed-off-by: Kalle Valo <kvalo@adurom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1251_rx.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.c190
1 files changed, 0 insertions, 190 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
deleted file mode 100644
index 25764592a59..00000000000
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ /dev/null
@@ -1,190 +0,0 @@
1/*
2 * This file is part of wl1251
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/skbuff.h>
24#include <linux/gfp.h>
25#include <net/mac80211.h>
26
27#include "wl1251.h"
28#include "wl1251_reg.h"
29#include "wl1251_io.h"
30#include "wl1251_rx.h"
31#include "wl1251_cmd.h"
32#include "wl1251_acx.h"
33
34static void wl1251_rx_header(struct wl1251 *wl,
35 struct wl1251_rx_descriptor *desc)
36{
37 u32 rx_packet_ring_addr;
38
39 rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
40 if (wl->rx_current_buffer)
41 rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
42
43 wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc));
44}
45
46static void wl1251_rx_status(struct wl1251 *wl,
47 struct wl1251_rx_descriptor *desc,
48 struct ieee80211_rx_status *status,
49 u8 beacon)
50{
51 u64 mactime;
52 int ret;
53
54 memset(status, 0, sizeof(struct ieee80211_rx_status));
55
56 status->band = IEEE80211_BAND_2GHZ;
57 status->mactime = desc->timestamp;
58
59 /*
60 * The rx status timestamp is a 32 bits value while the TSF is a
61 * 64 bits one.
62 * For IBSS merging, TSF is mandatory, so we have to get it
63 * somehow, so we ask for ACX_TSF_INFO.
64 * That could be moved to the get_tsf() hook, but unfortunately,
65 * this one must be atomic, while our SPI routines can sleep.
66 */
67 if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
68 ret = wl1251_acx_tsf_info(wl, &mactime);
69 if (ret == 0)
70 status->mactime = mactime;
71 }
72
73 status->signal = desc->rssi;
74
75 /*
76 * FIXME: guessing that snr needs to be divided by two, otherwise
77 * the values don't make any sense
78 */
79 wl->noise = desc->rssi - desc->snr / 2;
80
81 status->freq = ieee80211_channel_to_frequency(desc->channel);
82
83 status->flag |= RX_FLAG_TSFT;
84
85 if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
86 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
87
88 if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
89 status->flag |= RX_FLAG_DECRYPTED;
90
91 if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
92 status->flag |= RX_FLAG_MMIC_ERROR;
93 }
94
95 if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
96 status->flag |= RX_FLAG_FAILED_FCS_CRC;
97
98
99 /* FIXME: set status->rate_idx */
100}
101
102static void wl1251_rx_body(struct wl1251 *wl,
103 struct wl1251_rx_descriptor *desc)
104{
105 struct sk_buff *skb;
106 struct ieee80211_rx_status status;
107 u8 *rx_buffer, beacon = 0;
108 u16 length, *fc;
109 u32 curr_id, last_id_inc, rx_packet_ring_addr;
110
111 length = WL1251_RX_ALIGN(desc->length - PLCP_HEADER_LENGTH);
112 curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
113 last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
114
115 if (last_id_inc != curr_id) {
116 wl1251_warning("curr ID:%d, last ID inc:%d",
117 curr_id, last_id_inc);
118 wl->rx_last_id = curr_id;
119 } else {
120 wl->rx_last_id = last_id_inc;
121 }
122
123 rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
124 sizeof(struct wl1251_rx_descriptor) + 20;
125 if (wl->rx_current_buffer)
126 rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
127
128 skb = __dev_alloc_skb(length, GFP_KERNEL);
129 if (!skb) {
130 wl1251_error("Couldn't allocate RX frame");
131 return;
132 }
133
134 rx_buffer = skb_put(skb, length);
135 wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
136
137 /* The actual lenght doesn't include the target's alignment */
138 skb->len = desc->length - PLCP_HEADER_LENGTH;
139
140 fc = (u16 *)skb->data;
141
142 if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
143 beacon = 1;
144
145 wl1251_rx_status(wl, desc, &status, beacon);
146
147 wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
148 beacon ? "beacon" : "");
149
150 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
151 ieee80211_rx_ni(wl->hw, skb);
152}
153
154static void wl1251_rx_ack(struct wl1251 *wl)
155{
156 u32 data, addr;
157
158 if (wl->rx_current_buffer) {
159 addr = ACX_REG_INTERRUPT_TRIG_H;
160 data = INTR_TRIG_RX_PROC1;
161 } else {
162 addr = ACX_REG_INTERRUPT_TRIG;
163 data = INTR_TRIG_RX_PROC0;
164 }
165
166 wl1251_reg_write32(wl, addr, data);
167
168 /* Toggle buffer ring */
169 wl->rx_current_buffer = !wl->rx_current_buffer;
170}
171
172
173void wl1251_rx(struct wl1251 *wl)
174{
175 struct wl1251_rx_descriptor *rx_desc;
176
177 if (wl->state != WL1251_STATE_ON)
178 return;
179
180 rx_desc = wl->rx_descriptor;
181
182 /* We first read the frame's header */
183 wl1251_rx_header(wl, rx_desc);
184
185 /* Now we can read the body */
186 wl1251_rx_body(wl, rx_desc);
187
188 /* Finally, we need to ACK the RX */
189 wl1251_rx_ack(wl);
190}