]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/staging-add-agnx-wireless-driver.patch
f49924dcb571428e341821b8e704f914ac94c778
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / staging-add-agnx-wireless-driver.patch
1 From e983cf526bfd8ea56b72490f7449c65ee4dd0a16 Mon Sep 17 00:00:00 2001
2 From: Li YanBo <dreamfly281@gmail.com>
3 Date: Mon, 27 Oct 2008 20:32:57 -0700
4 Subject: Staging: add agnx wireless driver
5 Patch-mainline: 2.6.28
6
7 From: Li YanBo <dreamfly281@gmail.com>
8
9 This driver is for the Airgo AGNX00 wireless chip.
10
11 From: Li YanBo <dreamfly281@gmail.com>
12 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
13 ---
14 drivers/staging/Kconfig | 2
15 drivers/staging/Makefile | 1
16 drivers/staging/agnx/Kconfig | 5
17 drivers/staging/agnx/Makefile | 8
18 drivers/staging/agnx/TODO | 22
19 drivers/staging/agnx/agnx.h | 156 ++++++
20 drivers/staging/agnx/debug.h | 418 ++++++++++++++++++
21 drivers/staging/agnx/pci.c | 650 ++++++++++++++++++++++++++++
22 drivers/staging/agnx/phy.c | 958 ++++++++++++++++++++++++++++++++++++++++++
23 drivers/staging/agnx/phy.h | 409 +++++++++++++++++
24 drivers/staging/agnx/rf.c | 894 +++++++++++++++++++++++++++++++++++++++
25 drivers/staging/agnx/sta.c | 219 +++++++++
26 drivers/staging/agnx/sta.h | 222 +++++++++
27 drivers/staging/agnx/table.c | 168 +++++++
28 drivers/staging/agnx/table.h | 10
29 drivers/staging/agnx/xmit.c | 819 +++++++++++++++++++++++++++++++++++
30 drivers/staging/agnx/xmit.h | 250 ++++++++++
31 17 files changed, 5211 insertions(+)
32 create mode 100644 drivers/staging/agnx/Kconfig
33 create mode 100644 drivers/staging/agnx/Makefile
34 create mode 100644 drivers/staging/agnx/TODO
35 create mode 100644 drivers/staging/agnx/agnx.h
36 create mode 100644 drivers/staging/agnx/debug.h
37 create mode 100644 drivers/staging/agnx/pci.c
38 create mode 100644 drivers/staging/agnx/phy.c
39 create mode 100644 drivers/staging/agnx/phy.h
40 create mode 100644 drivers/staging/agnx/rf.c
41 create mode 100644 drivers/staging/agnx/sta.c
42 create mode 100644 drivers/staging/agnx/sta.h
43 create mode 100644 drivers/staging/agnx/table.c
44 create mode 100644 drivers/staging/agnx/table.h
45 create mode 100644 drivers/staging/agnx/xmit.c
46 create mode 100644 drivers/staging/agnx/xmit.h
47
48 --- /dev/null
49 +++ b/drivers/staging/agnx/agnx.h
50 @@ -0,0 +1,156 @@
51 +#ifndef AGNX_H_
52 +#define AGNX_H_
53 +
54 +#include "xmit.h"
55 +
56 +#define PFX KBUILD_MODNAME ": "
57 +
58 +static inline u32 agnx_read32(void __iomem *mem_region, u32 offset)
59 +{
60 + return ioread32(mem_region + offset);
61 +}
62 +
63 +static inline void agnx_write32(void __iomem *mem_region, u32 offset, u32 val)
64 +{
65 + iowrite32(val, mem_region + offset);
66 +}
67 +
68 +/* static const struct ieee80211_rate agnx_rates_80211b[] = { */
69 +/* { .rate = 10, */
70 +/* .val = 0xa, */
71 +/* .flags = IEEE80211_RATE_CCK }, */
72 +/* { .rate = 20, */
73 +/* .val = 0x14, */
74 +/* .hw_value = -0x14, */
75 +/* .flags = IEEE80211_RATE_CCK_2 }, */
76 +/* { .rate = 55, */
77 +/* .val = 0x37, */
78 +/* .val2 = -0x37, */
79 +/* .flags = IEEE80211_RATE_CCK_2 }, */
80 +/* { .rate = 110, */
81 +/* .val = 0x6e, */
82 +/* .val2 = -0x6e, */
83 +/* .flags = IEEE80211_RATE_CCK_2 } */
84 +/* }; */
85 +
86 +
87 +static const struct ieee80211_rate agnx_rates_80211g[] = {
88 +/* { .bitrate = 10, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
89 +/* { .bitrate = 20, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
90 +/* { .bitrate = 55, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
91 +/* { .bitrate = 110, .hw_value = 4, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
92 + { .bitrate = 10, .hw_value = 1, },
93 + { .bitrate = 20, .hw_value = 2, },
94 + { .bitrate = 55, .hw_value = 3, },
95 + { .bitrate = 110, .hw_value = 4,},
96 +
97 + { .bitrate = 60, .hw_value = 0xB, },
98 + { .bitrate = 90, .hw_value = 0xF, },
99 + { .bitrate = 120, .hw_value = 0xA },
100 + { .bitrate = 180, .hw_value = 0xE, },
101 +// { .bitrate = 240, .hw_value = 0xd, },
102 + { .bitrate = 360, .hw_value = 0xD, },
103 + { .bitrate = 480, .hw_value = 0x8, },
104 + { .bitrate = 540, .hw_value = 0xC, },
105 +};
106 +
107 +static const struct ieee80211_channel agnx_channels[] = {
108 + { .center_freq = 2412, .hw_value = 1, },
109 + { .center_freq = 2417, .hw_value = 2, },
110 + { .center_freq = 2422, .hw_value = 3, },
111 + { .center_freq = 2427, .hw_value = 4, },
112 + { .center_freq = 2432, .hw_value = 5, },
113 + { .center_freq = 2437, .hw_value = 6, },
114 + { .center_freq = 2442, .hw_value = 7, },
115 + { .center_freq = 2447, .hw_value = 8, },
116 + { .center_freq = 2452, .hw_value = 9, },
117 + { .center_freq = 2457, .hw_value = 10, },
118 + { .center_freq = 2462, .hw_value = 11, },
119 + { .center_freq = 2467, .hw_value = 12, },
120 + { .center_freq = 2472, .hw_value = 13, },
121 + { .center_freq = 2484, .hw_value = 14, },
122 +};
123 +
124 +#define NUM_DRIVE_MODES 2
125 +/* Agnx operate mode */
126 +enum {
127 + AGNX_MODE_80211A,
128 + AGNX_MODE_80211A_OOB,
129 + AGNX_MODE_80211A_MIMO,
130 + AGNX_MODE_80211B_SHORT,
131 + AGNX_MODE_80211B_LONG,
132 + AGNX_MODE_80211G,
133 + AGNX_MODE_80211G_OOB,
134 + AGNX_MODE_80211G_MIMO,
135 +};
136 +
137 +enum {
138 + AGNX_UNINIT,
139 + AGNX_START,
140 + AGNX_STOP,
141 +};
142 +
143 +struct agnx_priv {
144 + struct pci_dev *pdev;
145 + struct ieee80211_hw *hw;
146 +
147 + spinlock_t lock;
148 + struct mutex mutex;
149 + unsigned int init_status;
150 +
151 + void __iomem *ctl; /* pointer to base ram address */
152 + void __iomem *data; /* pointer to mem region #2 */
153 +
154 + struct agnx_ring rx;
155 + struct agnx_ring txm;
156 + struct agnx_ring txd;
157 +
158 + /* Need volatile? */
159 + u32 irq_status;
160 +
161 + struct delayed_work periodic_work; /* Periodic tasks like recalibrate*/
162 + struct ieee80211_low_level_stats stats;
163 +
164 +// unsigned int phymode;
165 + int mode;
166 + int channel;
167 + u8 bssid[ETH_ALEN];
168 + u8 ssid[32];
169 + size_t ssid_len;
170 +
171 + u8 mac_addr[ETH_ALEN];
172 + u8 revid;
173 +
174 + struct ieee80211_supported_band band;
175 +};
176 +
177 +
178 +#define AGNX_CHAINS_MAX 6
179 +#define AGNX_PERIODIC_DELAY 60000 /* unit: ms */
180 +#define LOCAL_STAID 0 /* the station entry for the card itself */
181 +#define BSSID_STAID 1 /* the station entry for the bsssid AP */
182 +#define spi_delay() udelay(40)
183 +#define eeprom_delay() udelay(40)
184 +#define routing_table_delay() udelay(50)
185 +
186 +/* PDU pool MEM region #2 */
187 +#define AGNX_PDUPOOL 0x40000 /* PDU pool */
188 +#define AGNX_PDUPOOL_SIZE 0x8000 /* PDU pool size*/
189 +#define AGNX_PDU_TX_WQ 0x41000 /* PDU list TX workqueue */
190 +#define AGNX_PDU_FREE 0x41800 /* Free Pool */
191 +#define PDU_SIZE 0x80 /* Free Pool node size */
192 +#define PDU_FREE_CNT 0xd0 /* Free pool node count */
193 +
194 +
195 +/* RF stuffs */
196 +extern void rf_chips_init(struct agnx_priv *priv);
197 +extern void spi_rc_write(void __iomem *mem_region, u32 chip_ids, u32 sw);
198 +extern void calibrate_oscillator(struct agnx_priv *priv);
199 +extern void do_calibration(struct agnx_priv *priv);
200 +extern void antenna_calibrate(struct agnx_priv *priv);
201 +extern void __antenna_calibrate(struct agnx_priv *priv);
202 +extern void print_offsets(struct agnx_priv *priv);
203 +extern int agnx_set_channel(struct agnx_priv *priv, unsigned int channel);
204 +
205 +
206 +#endif /* AGNX_H_ */
207 --- /dev/null
208 +++ b/drivers/staging/agnx/debug.h
209 @@ -0,0 +1,418 @@
210 +#ifndef AGNX_DEBUG_H_
211 +#define AGNX_DEBUG_H_
212 +
213 +#include "agnx.h"
214 +#include "phy.h"
215 +#include "sta.h"
216 +#include "xmit.h"
217 +
218 +#define AGNX_TRACE printk(KERN_ERR PFX "function:%s line:%d\n", __func__, __LINE__)
219 +
220 +#define PRINTK_LE16(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.4x\n", le16_to_cpu(var))
221 +#define PRINTK_LE32(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.8x\n", le32_to_cpu(var))
222 +#define PRINTK_U8(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.2x\n", var)
223 +#define PRINTK_BE16(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.4x\n", be16_to_cpu(var))
224 +#define PRINTK_BE32(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.8x\n", be32_to_cpu(var))
225 +#define PRINTK_BITS(prefix, field) printk(KERN_DEBUG PFX #prefix ": " #field ": 0x%x\n", (reg & field) >> field##_SHIFT)
226 +
227 +static inline void agnx_bug(char *reason)
228 +{
229 + printk(KERN_ERR PFX "%s\n", reason);
230 + BUG();
231 +}
232 +
233 +static inline void agnx_print_desc(struct agnx_desc *desc)
234 +{
235 + u32 reg = be32_to_cpu(desc->frag);
236 +
237 + PRINTK_BITS(DESC, PACKET_LEN);
238 +
239 + if (reg & FIRST_FRAG) {
240 + PRINTK_BITS(DESC, FIRST_PACKET_MASK);
241 + PRINTK_BITS(DESC, FIRST_RESERV2);
242 + PRINTK_BITS(DESC, FIRST_TKIP_ERROR);
243 + PRINTK_BITS(DESC, FIRST_TKIP_PACKET);
244 + PRINTK_BITS(DESC, FIRST_RESERV1);
245 + PRINTK_BITS(DESC, FIRST_FRAG_LEN);
246 + } else {
247 + PRINTK_BITS(DESC, SUB_RESERV2);
248 + PRINTK_BITS(DESC, SUB_TKIP_ERROR);
249 + PRINTK_BITS(DESC, SUB_TKIP_PACKET);
250 + PRINTK_BITS(DESC, SUB_RESERV1);
251 + PRINTK_BITS(DESC, SUB_FRAG_LEN);
252 + }
253 +
254 + PRINTK_BITS(DESC, FIRST_FRAG);
255 + PRINTK_BITS(DESC, LAST_FRAG);
256 + PRINTK_BITS(DESC, OWNER);
257 +}
258 +
259 +
260 +static inline void dump_ieee80211b_phy_hdr(__be32 _11b0, __be32 _11b1)
261 +{
262 +
263 +}
264 +
265 +static inline void agnx_print_hdr(struct agnx_hdr *hdr)
266 +{
267 + u32 reg;
268 + int i;
269 +
270 + reg = be32_to_cpu(hdr->reg0);
271 + PRINTK_BITS(HDR, RTS);
272 + PRINTK_BITS(HDR, MULTICAST);
273 + PRINTK_BITS(HDR, ACK);
274 + PRINTK_BITS(HDR, TM);
275 + PRINTK_BITS(HDR, RELAY);
276 + PRINTK_BITS(HDR, REVISED_FCS);
277 + PRINTK_BITS(HDR, NEXT_BUFFER_ADDR);
278 +
279 + reg = be32_to_cpu(hdr->reg1);
280 + PRINTK_BITS(HDR, MAC_HDR_LEN);
281 + PRINTK_BITS(HDR, DURATION_OVERIDE);
282 + PRINTK_BITS(HDR, PHY_HDR_OVERIDE);
283 + PRINTK_BITS(HDR, CRC_FAIL);
284 + PRINTK_BITS(HDR, SEQUENCE_NUMBER);
285 + PRINTK_BITS(HDR, BUFF_HEAD_ADDR);
286 +
287 + reg = be32_to_cpu(hdr->reg2);
288 + PRINTK_BITS(HDR, PDU_COUNT);
289 + PRINTK_BITS(HDR, WEP_KEY);
290 + PRINTK_BITS(HDR, USES_WEP_KEY);
291 + PRINTK_BITS(HDR, KEEP_ALIVE);
292 + PRINTK_BITS(HDR, BUFF_TAIL_ADDR);
293 +
294 + reg = be32_to_cpu(hdr->reg3);
295 + PRINTK_BITS(HDR, CTS_11G);
296 + PRINTK_BITS(HDR, RTS_11G);
297 + PRINTK_BITS(HDR, FRAG_SIZE);
298 + PRINTK_BITS(HDR, PAYLOAD_LEN);
299 + PRINTK_BITS(HDR, FRAG_NUM);
300 +
301 + reg = be32_to_cpu(hdr->reg4);
302 + PRINTK_BITS(HDR, RELAY_STAID);
303 + PRINTK_BITS(HDR, STATION_ID);
304 + PRINTK_BITS(HDR, WORKQUEUE_ID);
305 +
306 + reg = be32_to_cpu(hdr->reg5);
307 + /* printf the route flag */
308 + PRINTK_BITS(HDR, ROUTE_HOST);
309 + PRINTK_BITS(HDR, ROUTE_CARD_CPU);
310 + PRINTK_BITS(HDR, ROUTE_ENCRYPTION);
311 + PRINTK_BITS(HDR, ROUTE_TX);
312 + PRINTK_BITS(HDR, ROUTE_RX1);
313 + PRINTK_BITS(HDR, ROUTE_RX2);
314 + PRINTK_BITS(HDR, ROUTE_COMPRESSION);
315 +
316 + PRINTK_BE32(HDR, hdr->_11g0);
317 + PRINTK_BE32(HDR, hdr->_11g1);
318 + PRINTK_BE32(HDR, hdr->_11b0);
319 + PRINTK_BE32(HDR, hdr->_11b1);
320 +
321 + dump_ieee80211b_phy_hdr(hdr->_11b0, hdr->_11b1);
322 +
323 + /* Fixme */
324 + for (i = 0; i < ARRAY_SIZE(hdr->mac_hdr); i++) {
325 + if (i == 0)
326 + printk(KERN_DEBUG PFX "IEEE80211 HDR: ");
327 + printk("%.2x ", hdr->mac_hdr[i]);
328 + if (i + 1 == ARRAY_SIZE(hdr->mac_hdr))
329 + printk("\n");
330 + }
331 +
332 + PRINTK_BE16(HDR, hdr->rts_duration);
333 + PRINTK_BE16(HDR, hdr->last_duration);
334 + PRINTK_BE16(HDR, hdr->sec_last_duration);
335 + PRINTK_BE16(HDR, hdr->other_duration);
336 + PRINTK_BE16(HDR, hdr->tx_other_duration);
337 + PRINTK_BE16(HDR, hdr->last_11g_len);
338 + PRINTK_BE16(HDR, hdr->other_11g_len);
339 + PRINTK_BE16(HDR, hdr->last_11b_len);
340 + PRINTK_BE16(HDR, hdr->other_11b_len);
341 +
342 + /* FIXME */
343 + reg = be16_to_cpu(hdr->reg6);
344 + PRINTK_BITS(HDR, MBF);
345 + PRINTK_BITS(HDR, RSVD4);
346 +
347 + PRINTK_BE16(HDR, hdr->rx_frag_stat);
348 +
349 + PRINTK_BE32(HDR, hdr->time_stamp);
350 + PRINTK_BE32(HDR, hdr->phy_stats_hi);
351 + PRINTK_BE32(HDR, hdr->phy_stats_lo);
352 + PRINTK_BE32(HDR, hdr->mic_key0);
353 + PRINTK_BE32(HDR, hdr->mic_key1);
354 +} /* agnx_print_hdr */
355 +
356 +
357 +static inline void agnx_print_rx_hdr(struct agnx_hdr *hdr)
358 +{
359 + agnx_print_hdr(hdr);
360 +
361 + PRINTK_BE16(HDR, hdr->rx.rx_packet_duration);
362 + PRINTK_BE16(HDR, hdr->rx.replay_cnt);
363 +
364 + PRINTK_U8(HDR, hdr->rx_channel);
365 +}
366 +
367 +static inline void agnx_print_tx_hdr(struct agnx_hdr *hdr)
368 +{
369 + agnx_print_hdr(hdr);
370 +
371 + PRINTK_U8(HDR, hdr->tx.long_retry_limit);
372 + PRINTK_U8(HDR, hdr->tx.short_retry_limit);
373 + PRINTK_U8(HDR, hdr->tx.long_retry_cnt);
374 + PRINTK_U8(HDR, hdr->tx.short_retry_cnt);
375 +
376 + PRINTK_U8(HDR, hdr->rx_channel);
377 +}
378 +
379 +static inline void
380 +agnx_print_sta_power(struct agnx_priv *priv, unsigned int sta_idx)
381 +{
382 + struct agnx_sta_power power;
383 + u32 reg;
384 +
385 + get_sta_power(priv, &power, sta_idx);
386 +
387 + reg = le32_to_cpu(power.reg);
388 + PRINTK_BITS(STA_POWER, SIGNAL);
389 + PRINTK_BITS(STA_POWER, RATE);
390 + PRINTK_BITS(STA_POWER, TIFS);
391 + PRINTK_BITS(STA_POWER, EDCF);
392 + PRINTK_BITS(STA_POWER, CHANNEL_BOND);
393 + PRINTK_BITS(STA_POWER, PHY_MODE);
394 + PRINTK_BITS(STA_POWER, POWER_LEVEL);
395 + PRINTK_BITS(STA_POWER, NUM_TRANSMITTERS);
396 +}
397 +
398 +static inline void
399 +agnx_print_sta_tx_wq(struct agnx_priv *priv, unsigned int sta_idx, unsigned int wq_idx)
400 +{
401 + struct agnx_sta_tx_wq tx_wq;
402 + u32 reg;
403 +
404 + get_sta_tx_wq(priv, &tx_wq, sta_idx, wq_idx);
405 +
406 + reg = le32_to_cpu(tx_wq.reg0);
407 + PRINTK_BITS(STA_TX_WQ, TAIL_POINTER);
408 + PRINTK_BITS(STA_TX_WQ, HEAD_POINTER_LOW);
409 +
410 + reg = le32_to_cpu(tx_wq.reg3);
411 + PRINTK_BITS(STA_TX_WQ, HEAD_POINTER_HIGH);
412 + PRINTK_BITS(STA_TX_WQ, ACK_POINTER_LOW);
413 +
414 + reg = le32_to_cpu(tx_wq.reg1);
415 + PRINTK_BITS(STA_TX_WQ, ACK_POINTER_HIGH);
416 + PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_TAIL_PACK_CNT);
417 + PRINTK_BITS(STA_TX_WQ, ACK_TIMOUT_TAIL_PACK_CNT);
418 +
419 + reg = le32_to_cpu(tx_wq.reg2);
420 + PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_WIN_LIM_BYTE_CNT);
421 + PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_WIN_LIM_FRAG_CNT);
422 + PRINTK_BITS(STA_TX_WQ, WORK_QUEUE_ACK_TYPE);
423 + PRINTK_BITS(STA_TX_WQ, WORK_QUEUE_VALID);
424 +}
425 +
426 +static inline void agnx_print_sta_traffic(struct agnx_sta_traffic *traffic)
427 +{
428 + u32 reg;
429 +
430 + reg = le32_to_cpu(traffic->reg0);
431 + PRINTK_BITS(STA_TRAFFIC, ACK_TIMOUT_CNT);
432 + PRINTK_BITS(STA_TRAFFIC, TRAFFIC_ACK_TYPE);
433 + PRINTK_BITS(STA_TRAFFIC, NEW_PACKET);
434 + PRINTK_BITS(STA_TRAFFIC, TRAFFIC_VALID);
435 + PRINTK_BITS(STA_TRAFFIC, RX_HDR_DESC_POINTER);
436 +
437 + reg = le32_to_cpu(traffic->reg1);
438 + PRINTK_BITS(STA_TRAFFIC, RX_PACKET_TIMESTAMP);
439 + PRINTK_BITS(STA_TRAFFIC, TRAFFIC_RESERVED);
440 + PRINTK_BITS(STA_TRAFFIC, SV);
441 + PRINTK_BITS(STA_TRAFFIC, RX_SEQUENCE_NUM);
442 +
443 + PRINTK_LE32(STA_TRAFFIC, traffic->tx_replay_cnt_low);
444 +
445 + PRINTK_LE16(STA_TRAFFIC, traffic->tx_replay_cnt_high);
446 + PRINTK_LE16(STA_TRAFFIC, traffic->rx_replay_cnt_high);
447 +
448 + PRINTK_LE32(STA_TRAFFIC, traffic->rx_replay_cnt_low);
449 +}
450 +
451 +static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx)
452 +{
453 + struct agnx_sta station;
454 + struct agnx_sta *sta = &station;
455 + u32 reg;
456 + unsigned int i;
457 +
458 + get_sta(priv, sta, sta_idx);
459 +
460 + for (i = 0; i < 4; i++)
461 + PRINTK_LE32(STA, sta->tx_session_keys[i]);
462 + for (i = 0; i < 4; i++)
463 + PRINTK_LE32(STA, sta->rx_session_keys[i]);
464 +
465 + reg = le32_to_cpu(sta->reg);
466 + PRINTK_BITS(STA, ID_1);
467 + PRINTK_BITS(STA, ID_0);
468 + PRINTK_BITS(STA, ENABLE_CONCATENATION);
469 + PRINTK_BITS(STA, ENABLE_DECOMPRESSION);
470 + PRINTK_BITS(STA, STA_RESERVED);
471 + PRINTK_BITS(STA, EAP);
472 + PRINTK_BITS(STA, ED_NULL);
473 + PRINTK_BITS(STA, ENCRYPTION_POLICY);
474 + PRINTK_BITS(STA, DEFINED_KEY_ID);
475 + PRINTK_BITS(STA, FIXED_KEY);
476 + PRINTK_BITS(STA, KEY_VALID);
477 + PRINTK_BITS(STA, STATION_VALID);
478 +
479 + PRINTK_LE32(STA, sta->tx_aes_blks_unicast);
480 + PRINTK_LE32(STA, sta->rx_aes_blks_unicast);
481 +
482 + PRINTK_LE16(STA, sta->aes_format_err_unicast_cnt);
483 + PRINTK_LE16(STA, sta->aes_replay_unicast);
484 +
485 + PRINTK_LE16(STA, sta->aes_decrypt_err_unicast);
486 + PRINTK_LE16(STA, sta->aes_decrypt_err_default);
487 +
488 + PRINTK_LE16(STA, sta->single_retry_packets);
489 + PRINTK_LE16(STA, sta->failed_tx_packets);
490 +
491 + PRINTK_LE16(STA, sta->muti_retry_packets);
492 + PRINTK_LE16(STA, sta->ack_timeouts);
493 +
494 + PRINTK_LE16(STA, sta->frag_tx_cnt);
495 + PRINTK_LE16(STA, sta->rts_brq_sent);
496 +
497 + PRINTK_LE16(STA, sta->tx_packets);
498 + PRINTK_LE16(STA, sta->cts_back_timeout);
499 +
500 + PRINTK_LE32(STA, sta->phy_stats_high);
501 + PRINTK_LE32(STA, sta->phy_stats_low);
502 +
503 +// for (i = 0; i < 8; i++)
504 + agnx_print_sta_traffic(sta->traffic + 0);
505 +
506 + PRINTK_LE16(STA, sta->traffic_class0_frag_success);
507 + PRINTK_LE16(STA, sta->traffic_class1_frag_success);
508 + PRINTK_LE16(STA, sta->traffic_class2_frag_success);
509 + PRINTK_LE16(STA, sta->traffic_class3_frag_success);
510 + PRINTK_LE16(STA, sta->traffic_class4_frag_success);
511 + PRINTK_LE16(STA, sta->traffic_class5_frag_success);
512 + PRINTK_LE16(STA, sta->traffic_class6_frag_success);
513 + PRINTK_LE16(STA, sta->traffic_class7_frag_success);
514 +
515 + PRINTK_LE16(STA, sta->num_frag_non_prime_rates);
516 + PRINTK_LE16(STA, sta->ack_timeout_non_prime_rates);
517 +}
518 +
519 +
520 +static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
521 +{
522 + u16 fctl;
523 + int hdrlen;
524 + DECLARE_MAC_BUF(mac);
525 +
526 + fctl = le16_to_cpu(hdr->frame_control);
527 + switch (fctl & IEEE80211_FCTL_FTYPE) {
528 + case IEEE80211_FTYPE_DATA:
529 + printk(PFX "%s DATA ", tag);
530 + break;
531 + case IEEE80211_FTYPE_CTL:
532 + printk(PFX "%s CTL ", tag);
533 + break;
534 + case IEEE80211_FTYPE_MGMT:
535 + printk(PFX "%s MGMT ", tag);
536 + switch(fctl & IEEE80211_FCTL_STYPE) {
537 + case IEEE80211_STYPE_ASSOC_REQ:
538 + printk("SubType: ASSOC_REQ ");
539 + break;
540 + case IEEE80211_STYPE_ASSOC_RESP:
541 + printk("SubType: ASSOC_RESP ");
542 + break;
543 + case IEEE80211_STYPE_REASSOC_REQ:
544 + printk("SubType: REASSOC_REQ ");
545 + break;
546 + case IEEE80211_STYPE_REASSOC_RESP:
547 + printk("SubType: REASSOC_RESP ");
548 + break;
549 + case IEEE80211_STYPE_PROBE_REQ:
550 + printk("SubType: PROBE_REQ ");
551 + break;
552 + case IEEE80211_STYPE_PROBE_RESP:
553 + printk("SubType: PROBE_RESP ");
554 + break;
555 + case IEEE80211_STYPE_BEACON:
556 + printk("SubType: BEACON ");
557 + break;
558 + case IEEE80211_STYPE_ATIM:
559 + printk("SubType: ATIM ");
560 + break;
561 + case IEEE80211_STYPE_DISASSOC:
562 + printk("SubType: DISASSOC ");
563 + break;
564 + case IEEE80211_STYPE_AUTH:
565 + printk("SubType: AUTH ");
566 + break;
567 + case IEEE80211_STYPE_DEAUTH:
568 + printk("SubType: DEAUTH ");
569 + break;
570 + case IEEE80211_STYPE_ACTION:
571 + printk("SubType: ACTION ");
572 + break;
573 + default:
574 + printk("SubType: Unknow\n");
575 + }
576 + break;
577 + default:
578 + printk(PFX "%s Packet type: Unknow\n", tag);
579 + }
580 +
581 + hdrlen = ieee80211_hdrlen(fctl);
582 +
583 + if (hdrlen >= 4)
584 + printk("FC=0x%04x DUR=0x%04x",
585 + fctl, le16_to_cpu(hdr->duration_id));
586 + if (hdrlen >= 10)
587 + printk(" A1=%s", print_mac(mac, hdr->addr1));
588 + if (hdrlen >= 16)
589 + printk(" A2=%s", print_mac(mac, hdr->addr2));
590 + if (hdrlen >= 24)
591 + printk(" A3=%s", print_mac(mac, hdr->addr3));
592 + if (hdrlen >= 30)
593 + printk(" A4=%s", print_mac(mac, hdr->addr4));
594 + printk("\n");
595 +}
596 +
597 +static inline void dump_txm_registers(struct agnx_priv *priv)
598 +{
599 + void __iomem *ctl = priv->ctl;
600 + int i;
601 + for (i = 0; i <=0x1e8; i += 4) {
602 + printk(KERN_DEBUG PFX "TXM: %x---> 0x%.8x\n", i, ioread32(ctl + i));
603 + }
604 +}
605 +static inline void dump_rxm_registers(struct agnx_priv *priv)
606 +{
607 + void __iomem *ctl = priv->ctl;
608 + int i;
609 + for (i = 0; i <=0x108; i += 4)
610 + printk(KERN_DEBUG PFX "RXM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2000 + i));
611 +}
612 +static inline void dump_bm_registers(struct agnx_priv *priv)
613 +{
614 + void __iomem *ctl = priv->ctl;
615 + int i;
616 + for (i = 0; i <=0x90; i += 4)
617 + printk(KERN_DEBUG PFX "BM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2c00 + i));
618 +}
619 +static inline void dump_cir_registers(struct agnx_priv *priv)
620 +{
621 + void __iomem *ctl = priv->ctl;
622 + int i;
623 + for (i = 0; i <=0xb8; i += 4)
624 + printk(KERN_DEBUG PFX "CIR: %x---> 0x%.8x\n", i, ioread32(ctl + 0x3000 + i));
625 +}
626 +
627 +#endif /* AGNX_DEBUG_H_ */
628 --- /dev/null
629 +++ b/drivers/staging/agnx/Kconfig
630 @@ -0,0 +1,5 @@
631 +config AGNX
632 + tristate "Wireless Airgo AGNX support"
633 + depends on WLAN_80211 && MAC80211
634 + ---help---
635 + This is an experimental driver for Airgo AGNX00 wireless chip.
636 --- /dev/null
637 +++ b/drivers/staging/agnx/Makefile
638 @@ -0,0 +1,8 @@
639 +obj-$(CONFIG_AGNX) += agnx.o
640 +
641 +agnx-objs := rf.o \
642 + pci.o \
643 + xmit.o \
644 + table.o \
645 + sta.o \
646 + phy.o
647 --- /dev/null
648 +++ b/drivers/staging/agnx/pci.c
649 @@ -0,0 +1,650 @@
650 +/**
651 + * Airgo MIMO wireless driver
652 + *
653 + * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
654 +
655 + * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
656 + * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
657 +
658 + * This program is free software; you can redistribute it and/or modify
659 + * it under the terms of the GNU General Public License version 2 as
660 + * published by the Free Software Foundation.
661 + */
662 +
663 +#include <linux/init.h>
664 +#include <linux/etherdevice.h>
665 +#include <linux/pci.h>
666 +#include <linux/delay.h>
667 +
668 +#include "agnx.h"
669 +#include "debug.h"
670 +#include "xmit.h"
671 +#include "phy.h"
672 +
673 +MODULE_AUTHOR("Li YanBo <dreamfly281@gmail.com>");
674 +MODULE_DESCRIPTION("Airgo MIMO PCI wireless driver");
675 +MODULE_LICENSE("GPL");
676 +
677 +static struct pci_device_id agnx_pci_id_tbl[] __devinitdata = {
678 + { PCI_DEVICE(0x17cb, 0x0001) }, /* Beklin F5d8010, Netgear WGM511 etc */
679 + { PCI_DEVICE(0x17cb, 0x0002) }, /* Netgear Wpnt511 */
680 + { 0 }
681 +};
682 +
683 +MODULE_DEVICE_TABLE(pci, agnx_pci_id_tbl);
684 +
685 +
686 +static inline void agnx_interrupt_ack(struct agnx_priv *priv, u32 *reason)
687 +{
688 + void __iomem *ctl = priv->ctl;
689 + u32 reg;
690 +
691 + if ( *reason & AGNX_STAT_RX ) {
692 + /* Mark complete RX */
693 + reg = ioread32(ctl + AGNX_CIR_RXCTL);
694 + reg |= 0x4;
695 + iowrite32(reg, ctl + AGNX_CIR_RXCTL);
696 + /* disable Rx interrupt */
697 + }
698 + if ( *reason & AGNX_STAT_TX ) {
699 + reg = ioread32(ctl + AGNX_CIR_TXDCTL);
700 + if (reg & 0x4) {
701 + iowrite32(reg, ctl + AGNX_CIR_TXDCTL);
702 + *reason |= AGNX_STAT_TXD;
703 + }
704 + reg = ioread32(ctl + AGNX_CIR_TXMCTL);
705 + if (reg & 0x4) {
706 + iowrite32(reg, ctl + AGNX_CIR_TXMCTL);
707 + *reason |= AGNX_STAT_TXM;
708 + }
709 + }
710 + if ( *reason & AGNX_STAT_X ) {
711 +/* reg = ioread32(ctl + AGNX_INT_STAT); */
712 +/* iowrite32(reg, ctl + AGNX_INT_STAT); */
713 +/* /\* FIXME reinit interrupt mask *\/ */
714 +/* reg = 0xc390bf9 & ~IRQ_TX_BEACON; */
715 +/* reg &= ~IRQ_TX_DISABLE; */
716 +/* iowrite32(reg, ctl + AGNX_INT_MASK); */
717 +/* iowrite32(0x800, ctl + AGNX_CIR_BLKCTL); */
718 + }
719 +} /* agnx_interrupt_ack */
720 +
721 +static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
722 +{
723 + struct ieee80211_hw *dev = dev_id;
724 + struct agnx_priv *priv = dev->priv;
725 + void __iomem *ctl = priv->ctl;
726 + irqreturn_t ret = IRQ_NONE;
727 + u32 irq_reason;
728 +
729 + spin_lock(&priv->lock);
730 +
731 +// printk(KERN_ERR PFX "Get a interrupt %s\n", __func__);
732 +
733 + if (priv->init_status != AGNX_START)
734 + goto out;
735 +
736 + /* FiXME Here has no lock, Is this will lead to race? */
737 + irq_reason = ioread32(ctl + AGNX_CIR_BLKCTL);
738 + if (!(irq_reason & 0x7))
739 + goto out;
740 +
741 + ret = IRQ_HANDLED;
742 + priv->irq_status = ioread32(ctl + AGNX_INT_STAT);
743 +
744 +// printk(PFX "Interrupt reason is 0x%x\n", irq_reason);
745 + /* Make sure the txm and txd flags don't conflict with other unknown
746 + interrupt flag, maybe is not necessary */
747 + irq_reason &= 0xF;
748 +
749 + disable_rx_interrupt(priv);
750 + /* TODO Make sure the card finished initialized */
751 + agnx_interrupt_ack(priv, &irq_reason);
752 +
753 + if ( irq_reason & AGNX_STAT_RX )
754 + handle_rx_irq(priv);
755 + if ( irq_reason & AGNX_STAT_TXD )
756 + handle_txd_irq(priv);
757 + if ( irq_reason & AGNX_STAT_TXM )
758 + handle_txm_irq(priv);
759 + if ( irq_reason & AGNX_STAT_X )
760 + handle_other_irq(priv);
761 +
762 + enable_rx_interrupt(priv);
763 +out:
764 + spin_unlock(&priv->lock);
765 + return ret;
766 +} /* agnx_interrupt_handler */
767 +
768 +
769 +/* FIXME */
770 +static int agnx_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
771 +{
772 + AGNX_TRACE;
773 + return _agnx_tx(dev->priv, skb);
774 +} /* agnx_tx */
775 +
776 +
777 +static int agnx_get_mac_address(struct agnx_priv *priv)
778 +{
779 + void __iomem *ctl = priv->ctl;
780 + u32 reg;
781 + AGNX_TRACE;
782 +
783 + /* Attention! directly read the MAC or other date from EEPROM will
784 + lead to cardbus(WGM511) lock up when write to PM PLL register */
785 + reg = agnx_read32(ctl, 0x3544);
786 + udelay(40);
787 + reg = agnx_read32(ctl, 0x354c);
788 + udelay(50);
789 + /* Get the mac address */
790 + reg = agnx_read32(ctl, 0x3544);
791 + udelay(40);
792 +
793 + /* HACK */
794 + reg = cpu_to_le32(reg);
795 + priv->mac_addr[0] = ((u8 *)&reg)[2];
796 + priv->mac_addr[1] = ((u8 *)&reg)[3];
797 + reg = agnx_read32(ctl, 0x3548);
798 + udelay(50);
799 + *((u32 *)(priv->mac_addr + 2)) = cpu_to_le32(reg);
800 +
801 + if (!is_valid_ether_addr(priv->mac_addr)) {
802 + DECLARE_MAC_BUF(mbuf);
803 + printk(KERN_WARNING PFX "read mac %s\n", print_mac(mbuf, priv->mac_addr));
804 + printk(KERN_WARNING PFX "Invalid hwaddr! Using random hwaddr\n");
805 + random_ether_addr(priv->mac_addr);
806 + }
807 +
808 + return 0;
809 +} /* agnx_get_mac_address */
810 +
811 +static int agnx_alloc_rings(struct agnx_priv *priv)
812 +{
813 + unsigned int len;
814 + AGNX_TRACE;
815 +
816 + /* Allocate RX/TXM/TXD rings info */
817 + priv->rx.size = AGNX_RX_RING_SIZE;
818 + priv->txm.size = AGNX_TXM_RING_SIZE;
819 + priv->txd.size = AGNX_TXD_RING_SIZE;
820 +
821 + len = priv->rx.size + priv->txm.size + priv->txd.size;
822 +
823 +// priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL);
824 + priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_ATOMIC);
825 + if (!priv->rx.info)
826 + return -ENOMEM;
827 + priv->txm.info = priv->rx.info + priv->rx.size;
828 + priv->txd.info = priv->txm.info + priv->txm.size;
829 +
830 + /* Allocate RX/TXM/TXD descriptors */
831 + priv->rx.desc = pci_alloc_consistent(priv->pdev, sizeof(struct agnx_desc) * len,
832 + &priv->rx.dma);
833 + if (!priv->rx.desc) {
834 + kfree(priv->rx.info);
835 + return -ENOMEM;
836 + }
837 +
838 + priv->txm.desc = priv->rx.desc + priv->rx.size;
839 + priv->txm.dma = priv->rx.dma + sizeof(struct agnx_desc) * priv->rx.size;
840 + priv->txd.desc = priv->txm.desc + priv->txm.size;
841 + priv->txd.dma = priv->txm.dma + sizeof(struct agnx_desc) * priv->txm.size;
842 +
843 + return 0;
844 +} /* agnx_alloc_rings */
845 +
846 +static void rings_free(struct agnx_priv *priv)
847 +{
848 + unsigned int len = priv->rx.size + priv->txm.size + priv->txd.size;
849 + unsigned long flags;
850 + AGNX_TRACE;
851 +
852 + spin_lock_irqsave(&priv->lock, flags);
853 + kfree(priv->rx.info);
854 + pci_free_consistent(priv->pdev, sizeof(struct agnx_desc) * len,
855 + priv->rx.desc, priv->rx.dma);
856 + spin_unlock_irqrestore(&priv->lock, flags);
857 +}
858 +
859 +
860 +static void agnx_periodic_work_handler(struct work_struct *work)
861 +{
862 + struct agnx_priv *priv = container_of(work, struct agnx_priv,
863 + periodic_work.work);
864 +// unsigned long flags;
865 + unsigned long delay;
866 +
867 + /* fixme: using mutex?? */
868 +// spin_lock_irqsave(&priv->lock, flags);
869 +
870 + /* TODO Recalibrate*/
871 +// calibrate_oscillator(priv);
872 +// antenna_calibrate(priv);
873 +// agnx_send_packet(priv, 997);
874 + /* FIXME */
875 +/* if (debug == 3) */
876 +/* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
877 +/* else */
878 + delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY);
879 +// delay = round_jiffies(HZ * 15);
880 +
881 + queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay);
882 +
883 +// spin_unlock_irqrestore(&priv->lock, flags);
884 +}
885 +
886 +
887 +static int agnx_start(struct ieee80211_hw *dev)
888 +{
889 + struct agnx_priv *priv = dev->priv;
890 + unsigned long delay;
891 + int err = 0;
892 + AGNX_TRACE;
893 +
894 + err = agnx_alloc_rings(priv);
895 + if (err) {
896 + printk(KERN_ERR PFX "Can't alloc RX/TXM/TXD rings\n");
897 + goto out;
898 + }
899 + err = request_irq(priv->pdev->irq, &agnx_interrupt_handler,
900 + IRQF_SHARED, "agnx_pci", dev);
901 + if (err) {
902 + printk(KERN_ERR PFX "Failed to register IRQ handler\n");
903 + rings_free(priv);
904 + goto out;
905 + }
906 +
907 +// mdelay(500);
908 +
909 + might_sleep();
910 + agnx_hw_init(priv);
911 +
912 +// mdelay(500);
913 + might_sleep();
914 +
915 + priv->init_status = AGNX_START;
916 +/* INIT_DELAYED_WORK(&priv->periodic_work, agnx_periodic_work_handler); */
917 +/* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
918 +/* queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay); */
919 +out:
920 + return err;
921 +} /* agnx_start */
922 +
923 +static void agnx_stop(struct ieee80211_hw *dev)
924 +{
925 + struct agnx_priv *priv = dev->priv;
926 + AGNX_TRACE;
927 +
928 + priv->init_status = AGNX_STOP;
929 + /* make sure hardware will not generate irq */
930 + agnx_hw_reset(priv);
931 + free_irq(priv->pdev->irq, dev);
932 + flush_workqueue(priv->hw->workqueue);
933 +// cancel_delayed_work_sync(&priv->periodic_work);
934 + unfill_rings(priv);
935 + rings_free(priv);
936 +}
937 +
938 +static int agnx_config(struct ieee80211_hw *dev,
939 + struct ieee80211_conf *conf)
940 +{
941 + struct agnx_priv *priv = dev->priv;
942 + int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
943 + AGNX_TRACE;
944 +
945 + spin_lock(&priv->lock);
946 + /* FIXME need priv lock? */
947 + if (channel != priv->channel) {
948 + priv->channel = channel;
949 + agnx_set_channel(priv, priv->channel);
950 + }
951 +
952 + spin_unlock(&priv->lock);
953 + return 0;
954 +}
955 +
956 +static int agnx_config_interface(struct ieee80211_hw *dev,
957 + struct ieee80211_vif *vif,
958 + struct ieee80211_if_conf *conf)
959 +{
960 + struct agnx_priv *priv = dev->priv;
961 + void __iomem *ctl = priv->ctl;
962 + AGNX_TRACE;
963 +
964 + spin_lock(&priv->lock);
965 +
966 + if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
967 +// u32 reghi, reglo;
968 + agnx_set_bssid(priv, conf->bssid);
969 + memcpy(priv->bssid, conf->bssid, ETH_ALEN);
970 + hash_write(priv, conf->bssid, BSSID_STAID);
971 + sta_init(priv, BSSID_STAID);
972 + /* FIXME needed? */
973 + sta_power_init(priv, BSSID_STAID);
974 + agnx_write32(ctl, AGNX_BM_MTSM, 0xff & ~0x1);
975 + }
976 + if (conf->ssid_len != priv->ssid_len ||
977 + memcmp(conf->ssid, priv->ssid, conf->ssid_len)) {
978 + agnx_set_ssid(priv, conf->ssid, conf->ssid_len);
979 + priv->ssid_len = conf->ssid_len;
980 + memcpy(priv->ssid, conf->ssid, conf->ssid_len);
981 + }
982 + spin_unlock(&priv->lock);
983 + return 0;
984 +} /* agnx_config_interface */
985 +
986 +
987 +static void agnx_configure_filter(struct ieee80211_hw *dev,
988 + unsigned int changed_flags,
989 + unsigned int *total_flags,
990 + int mc_count, struct dev_mc_list *mclist)
991 +{
992 + unsigned int new_flags = 0;
993 +
994 + *total_flags = new_flags;
995 + /* TODO */
996 +}
997 +
998 +static int agnx_add_interface(struct ieee80211_hw *dev,
999 + struct ieee80211_if_init_conf *conf)
1000 +{
1001 + struct agnx_priv *priv = dev->priv;
1002 + AGNX_TRACE;
1003 +
1004 + spin_lock(&priv->lock);
1005 + /* FIXME */
1006 + if (priv->mode != NL80211_IFTYPE_MONITOR)
1007 + return -EOPNOTSUPP;
1008 +
1009 + switch (conf->type) {
1010 + case NL80211_IFTYPE_STATION:
1011 + priv->mode = conf->type;
1012 + break;
1013 + default:
1014 + return -EOPNOTSUPP;
1015 + }
1016 +
1017 + spin_unlock(&priv->lock);
1018 +
1019 + return 0;
1020 +}
1021 +
1022 +static void agnx_remove_interface(struct ieee80211_hw *dev,
1023 + struct ieee80211_if_init_conf *conf)
1024 +{
1025 + struct agnx_priv *priv = dev->priv;
1026 + AGNX_TRACE;
1027 +
1028 + /* TODO */
1029 + priv->mode = NL80211_IFTYPE_MONITOR;
1030 +}
1031 +
1032 +static int agnx_get_stats(struct ieee80211_hw *dev,
1033 + struct ieee80211_low_level_stats *stats)
1034 +{
1035 + struct agnx_priv *priv = dev->priv;
1036 + AGNX_TRACE;
1037 + spin_lock(&priv->lock);
1038 + /* TODO !! */
1039 + memcpy(stats, &priv->stats, sizeof(*stats));
1040 + spin_unlock(&priv->lock);
1041 +
1042 + return 0;
1043 +}
1044 +
1045 +static u64 agnx_get_tsft(struct ieee80211_hw *dev)
1046 +{
1047 + void __iomem *ctl = ((struct agnx_priv *)dev->priv)->ctl;
1048 + u32 tsftl;
1049 + u64 tsft;
1050 + AGNX_TRACE;
1051 +
1052 + /* FIXME */
1053 + tsftl = ioread32(ctl + AGNX_TXM_TIMESTAMPLO);
1054 + tsft = ioread32(ctl + AGNX_TXM_TIMESTAMPHI);
1055 + tsft <<= 32;
1056 + tsft |= tsftl;
1057 +
1058 + return tsft;
1059 +}
1060 +
1061 +static int agnx_get_tx_stats(struct ieee80211_hw *dev,
1062 + struct ieee80211_tx_queue_stats *stats)
1063 +{
1064 + struct agnx_priv *priv = dev->priv;
1065 + AGNX_TRACE;
1066 +
1067 + /* FIXME now we just using txd queue, but should using txm queue too */
1068 + stats[0].len = (priv->txd.idx - priv->txd.idx_sent) / 2;
1069 + stats[0].limit = priv->txd.size - 2;
1070 + stats[0].count = priv->txd.idx / 2;
1071 +
1072 + return 0;
1073 +}
1074 +
1075 +static struct ieee80211_ops agnx_ops = {
1076 + .tx = agnx_tx,
1077 + .start = agnx_start,
1078 + .stop = agnx_stop,
1079 + .add_interface = agnx_add_interface,
1080 + .remove_interface = agnx_remove_interface,
1081 + .config = agnx_config,
1082 + .config_interface = agnx_config_interface,
1083 + .configure_filter = agnx_configure_filter,
1084 + .get_stats = agnx_get_stats,
1085 + .get_tx_stats = agnx_get_tx_stats,
1086 + .get_tsf = agnx_get_tsft
1087 +};
1088 +
1089 +static void __devexit agnx_pci_remove(struct pci_dev *pdev)
1090 +{
1091 + struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1092 + struct agnx_priv *priv = dev->priv;
1093 + AGNX_TRACE;
1094 +
1095 + if (!dev)
1096 + return;
1097 + ieee80211_unregister_hw(dev);
1098 + pci_iounmap(pdev, priv->ctl);
1099 + pci_iounmap(pdev, priv->data);
1100 + pci_release_regions(pdev);
1101 + pci_disable_device(pdev);
1102 +
1103 + ieee80211_free_hw(dev);
1104 +}
1105 +
1106 +static int __devinit agnx_pci_probe(struct pci_dev *pdev,
1107 + const struct pci_device_id *id)
1108 +{
1109 + struct ieee80211_hw *dev;
1110 + struct agnx_priv *priv;
1111 + u32 mem_addr0, mem_len0;
1112 + u32 mem_addr1, mem_len1;
1113 + int err;
1114 + DECLARE_MAC_BUF(mac);
1115 +
1116 + err = pci_enable_device(pdev);
1117 + if (err) {
1118 + printk(KERN_ERR PFX "Can't enable new PCI device\n");
1119 + return err;
1120 + }
1121 +
1122 + /* get pci resource */
1123 + mem_addr0 = pci_resource_start(pdev, 0);
1124 + mem_len0 = pci_resource_len(pdev, 0);
1125 + mem_addr1 = pci_resource_start(pdev, 1);
1126 + mem_len1 = pci_resource_len(pdev, 1);
1127 + printk(KERN_DEBUG PFX "Memaddr0 is %x, length is %x\n", mem_addr0, mem_len0);
1128 + printk(KERN_DEBUG PFX "Memaddr1 is %x, length is %x\n", mem_addr1, mem_len1);
1129 +
1130 + err = pci_request_regions(pdev, "agnx-pci");
1131 + if (err) {
1132 + printk(KERN_ERR PFX "Can't obtain PCI resource\n");
1133 + return err;
1134 + }
1135 +
1136 + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
1137 + pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
1138 + printk(KERN_ERR PFX "No suitable DMA available\n");
1139 + goto err_free_reg;
1140 + }
1141 +
1142 + pci_set_master(pdev);
1143 + printk(KERN_DEBUG PFX "pdev->irq is %d\n", pdev->irq);
1144 +
1145 + dev = ieee80211_alloc_hw(sizeof(*priv), &agnx_ops);
1146 + if (!dev) {
1147 + printk(KERN_ERR PFX "ieee80211 alloc failed\n");
1148 + err = -ENOMEM;
1149 + goto err_free_reg;
1150 + }
1151 + /* init priv */
1152 + priv = dev->priv;
1153 + memset(priv, 0, sizeof(*priv));
1154 + priv->mode = NL80211_IFTYPE_MONITOR;
1155 + priv->pdev = pdev;
1156 + priv->hw = dev;
1157 + spin_lock_init(&priv->lock);
1158 + priv->init_status = AGNX_UNINIT;
1159 +
1160 + /* Map mem #1 and #2 */
1161 + priv->ctl = pci_iomap(pdev, 0, mem_len0);
1162 +// printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl);
1163 + if (!priv->ctl) {
1164 + printk(KERN_ERR PFX "Can't map device memory\n");
1165 + goto err_free_dev;
1166 + }
1167 + priv->data = pci_iomap(pdev, 1, mem_len1);
1168 + printk(KERN_DEBUG PFX "MEM2 mapped address is 0x%p\n", priv->data);
1169 + if (!priv->data) {
1170 + printk(KERN_ERR PFX "Can't map device memory\n");
1171 + goto err_iounmap2;
1172 + }
1173 +
1174 + pci_read_config_byte(pdev, PCI_REVISION_ID, &priv->revid);
1175 +
1176 + priv->band.channels = (struct ieee80211_channel *)agnx_channels;
1177 + priv->band.n_channels = ARRAY_SIZE(agnx_channels);
1178 + priv->band.bitrates = (struct ieee80211_rate *)agnx_rates_80211g;
1179 + priv->band.n_bitrates = ARRAY_SIZE(agnx_rates_80211g);
1180 +
1181 + /* Init ieee802.11 dev */
1182 + SET_IEEE80211_DEV(dev, &pdev->dev);
1183 + pci_set_drvdata(pdev, dev);
1184 + dev->extra_tx_headroom = sizeof(struct agnx_hdr);
1185 +
1186 + /* FIXME It only include FCS in promious mode but not manage mode */
1187 +/* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS; */
1188 + dev->channel_change_time = 5000;
1189 + dev->max_signal = 100;
1190 + /* FIXME */
1191 + dev->queues = 1;
1192 +
1193 + agnx_get_mac_address(priv);
1194 +
1195 + SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr);
1196 +
1197 +/* /\* FIXME *\/ */
1198 +/* for (i = 1; i < NUM_DRIVE_MODES; i++) { */
1199 +/* err = ieee80211_register_hwmode(dev, &priv->modes[i]); */
1200 +/* if (err) { */
1201 +/* printk(KERN_ERR PFX "Can't register hwmode\n"); */
1202 +/* goto err_iounmap; */
1203 +/* } */
1204 +/* } */
1205 +
1206 + priv->channel = 1;
1207 + dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
1208 +
1209 + err = ieee80211_register_hw(dev);
1210 + if (err) {
1211 + printk(KERN_ERR PFX "Can't register hardware\n");
1212 + goto err_iounmap;
1213 + }
1214 +
1215 + agnx_hw_reset(priv);
1216 +
1217 +
1218 + printk(PFX "%s: hwaddr %s, Rev 0x%02x\n", wiphy_name(dev->wiphy),
1219 + print_mac(mac, dev->wiphy->perm_addr), priv->revid);
1220 + return 0;
1221 +
1222 + err_iounmap:
1223 + pci_iounmap(pdev, priv->data);
1224 +
1225 + err_iounmap2:
1226 + pci_iounmap(pdev, priv->ctl);
1227 +
1228 + err_free_dev:
1229 + pci_set_drvdata(pdev, NULL);
1230 + ieee80211_free_hw(dev);
1231 +
1232 + err_free_reg:
1233 + pci_release_regions(pdev);
1234 +
1235 + pci_disable_device(pdev);
1236 + return err;
1237 +} /* agnx_pci_probe*/
1238 +
1239 +#ifdef CONFIG_PM
1240 +
1241 +static int agnx_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1242 +{
1243 + struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1244 + AGNX_TRACE;
1245 +
1246 + ieee80211_stop_queues(dev);
1247 + agnx_stop(dev);
1248 +
1249 + pci_save_state(pdev);
1250 + pci_set_power_state(pdev, pci_choose_state(pdev, state));
1251 + return 0;
1252 +}
1253 +
1254 +static int agnx_pci_resume(struct pci_dev *pdev)
1255 +{
1256 + struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1257 + AGNX_TRACE;
1258 +
1259 + pci_set_power_state(pdev, PCI_D0);
1260 + pci_restore_state(pdev);
1261 +
1262 + agnx_start(dev);
1263 + ieee80211_wake_queues(dev);
1264 +
1265 + return 0;
1266 +}
1267 +
1268 +#else
1269 +
1270 +#define agnx_pci_suspend NULL
1271 +#define agnx_pci_resume NULL
1272 +
1273 +#endif /* CONFIG_PM */
1274 +
1275 +
1276 +static struct pci_driver agnx_pci_driver = {
1277 + .name = "agnx-pci",
1278 + .id_table = agnx_pci_id_tbl,
1279 + .probe = agnx_pci_probe,
1280 + .remove = __devexit_p(agnx_pci_remove),
1281 + .suspend = agnx_pci_suspend,
1282 + .resume = agnx_pci_resume,
1283 +};
1284 +
1285 +static int __init agnx_pci_init(void)
1286 +{
1287 + AGNX_TRACE;
1288 + return pci_register_driver(&agnx_pci_driver);
1289 +}
1290 +
1291 +static void __exit agnx_pci_exit(void)
1292 +{
1293 + AGNX_TRACE;
1294 + pci_unregister_driver(&agnx_pci_driver);
1295 +}
1296 +
1297 +
1298 +module_init(agnx_pci_init);
1299 +module_exit(agnx_pci_exit);
1300 --- /dev/null
1301 +++ b/drivers/staging/agnx/phy.c
1302 @@ -0,0 +1,958 @@
1303 +/**
1304 + * Airgo MIMO wireless driver
1305 + *
1306 + * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
1307 +
1308 + * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
1309 + * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
1310 +
1311 + * This program is free software; you can redistribute it and/or modify
1312 + * it under the terms of the GNU General Public License version 2 as
1313 + * published by the Free Software Foundation.
1314 + */
1315 +
1316 +#include <linux/init.h>
1317 +#include <linux/etherdevice.h>
1318 +#include <linux/pci.h>
1319 +#include <linux/delay.h>
1320 +#include "agnx.h"
1321 +#include "debug.h"
1322 +#include "phy.h"
1323 +#include "table.h"
1324 +#include "sta.h"
1325 +#include "xmit.h"
1326 +
1327 +u8 read_from_eeprom(struct agnx_priv *priv, u16 address)
1328 +{
1329 + void __iomem *ctl = priv->ctl;
1330 + struct agnx_eeprom cmd;
1331 + u32 reg;
1332 +
1333 + memset(&cmd, 0, sizeof(cmd));
1334 + cmd.cmd = EEPROM_CMD_READ << AGNX_EEPROM_COMMAND_SHIFT;
1335 + cmd.address = address;
1336 + /* Verify that the Status bit is clear */
1337 + /* Read Command and Address are written to the Serial Interface */
1338 + iowrite32(*(__le32 *)&cmd, ctl + AGNX_CIR_SERIALITF);
1339 + /* Wait for the Status bit to clear again */
1340 + eeprom_delay();
1341 + /* Read from Data */
1342 + reg = ioread32(ctl + AGNX_CIR_SERIALITF);
1343 +
1344 + cmd = *(struct agnx_eeprom *)&reg;
1345 +
1346 + return cmd.data;
1347 +}
1348 +
1349 +static int card_full_reset(struct agnx_priv *priv)
1350 +{
1351 + void __iomem *ctl = priv->ctl;
1352 + u32 reg;
1353 + AGNX_TRACE;
1354 +
1355 + reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
1356 + agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x80);
1357 + reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
1358 + return 0;
1359 +}
1360 +
1361 +inline void enable_power_saving(struct agnx_priv *priv)
1362 +{
1363 + void __iomem *ctl = priv->ctl;
1364 + u32 reg;
1365 +
1366 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
1367 + reg &= ~0x8;
1368 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
1369 +}
1370 +
1371 +inline void disable_power_saving(struct agnx_priv *priv)
1372 +{
1373 + void __iomem *ctl = priv->ctl;
1374 + u32 reg;
1375 +
1376 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
1377 + reg |= 0x8;
1378 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
1379 +}
1380 +
1381 +
1382 +void disable_receiver(struct agnx_priv *priv)
1383 +{
1384 + void __iomem *ctl = priv->ctl;
1385 + AGNX_TRACE;
1386 +
1387 + /* FIXME Disable the receiver */
1388 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x0);
1389 + /* Set gain control reset */
1390 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
1391 + /* Reset gain control reset */
1392 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
1393 +}
1394 +
1395 +
1396 +/* Fixme this shoule be disable RX, above is enable RX */
1397 +void enable_receiver(struct agnx_priv *priv)
1398 +{
1399 + void __iomem *ctl = priv->ctl;
1400 + AGNX_TRACE;
1401 +
1402 + /* Set adaptive gain control discovery mode */
1403 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
1404 + /* Set gain control reset */
1405 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
1406 + /* Clear gain control reset */
1407 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
1408 +}
1409 +
1410 +static void mac_address_set(struct agnx_priv *priv)
1411 +{
1412 + void __iomem *ctl = priv->ctl;
1413 + u8 *mac_addr = priv->mac_addr;
1414 + u32 reg;
1415 +
1416 + /* FIXME */
1417 + reg = (mac_addr[0] << 24) | (mac_addr[1] << 16) | mac_addr[2] << 8 | mac_addr[3];
1418 + iowrite32(reg, ctl + AGNX_RXM_MACHI);
1419 + reg = (mac_addr[4] << 8) | mac_addr[5];
1420 + iowrite32(reg, ctl + AGNX_RXM_MACLO);
1421 +}
1422 +
1423 +static void receiver_bssid_set(struct agnx_priv *priv, u8 *bssid)
1424 +{
1425 + void __iomem *ctl = priv->ctl;
1426 + u32 reg;
1427 +
1428 + disable_receiver(priv);
1429 + /* FIXME */
1430 + reg = bssid[0] << 24 | (bssid[1] << 16) | (bssid[2] << 8) | bssid[3];
1431 + iowrite32(reg, ctl + AGNX_RXM_BSSIDHI);
1432 + reg = (bssid[4] << 8) | bssid[5];
1433 + iowrite32(reg, ctl + AGNX_RXM_BSSIDLO);
1434 +
1435 + /* Enable the receiver */
1436 + enable_receiver(priv);
1437 +
1438 + /* Clear the TSF */
1439 +/* agnx_write32(ctl, AGNX_TXM_TSFLO, 0x0); */
1440 +/* agnx_write32(ctl, AGNX_TXM_TSFHI, 0x0); */
1441 + /* Clear the TBTT */
1442 + agnx_write32(ctl, AGNX_TXM_TBTTLO, 0x0);
1443 + agnx_write32(ctl, AGNX_TXM_TBTTHI, 0x0);
1444 + disable_receiver(priv);
1445 +} /* receiver_bssid_set */
1446 +
1447 +static void band_management_init(struct agnx_priv *priv)
1448 +{
1449 + void __iomem *ctl = priv->ctl;
1450 + void __iomem *data = priv->data;
1451 + u32 reg;
1452 + int i;
1453 + AGNX_TRACE;
1454 +
1455 + agnx_write32(ctl, AGNX_BM_TXWADDR, AGNX_PDU_TX_WQ);
1456 + agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0);
1457 + memset_io(data + AGNX_PDUPOOL, 0x0, AGNX_PDUPOOL_SIZE);
1458 + agnx_write32(ctl, AGNX_BM_BMCTL, 0x200);
1459 +
1460 + agnx_write32(ctl, AGNX_BM_CIPDUWCNT, 0x40);
1461 + agnx_write32(ctl, AGNX_BM_SPPDUWCNT, 0x2);
1462 + agnx_write32(ctl, AGNX_BM_RFPPDUWCNT, 0x0);
1463 + agnx_write32(ctl, AGNX_BM_RHPPDUWCNT, 0x22);
1464 +
1465 + /* FIXME Initialize the Free Pool Linked List */
1466 + /* 1. Write the Address of the Next Node ((0x41800 + node*size)/size)
1467 + to the first word of each node. */
1468 + for (i = 0; i < PDU_FREE_CNT; i++) {
1469 + iowrite32((AGNX_PDU_FREE + (i+1)*PDU_SIZE)/PDU_SIZE,
1470 + data + AGNX_PDU_FREE + (PDU_SIZE * i));
1471 + /* The last node should be set to 0x0 */
1472 + if ((i + 1) == PDU_FREE_CNT)
1473 + memset_io(data + AGNX_PDU_FREE + (PDU_SIZE * i),
1474 + 0x0, PDU_SIZE);
1475 + }
1476 +
1477 + /* Head is First Pool address (0x41800) / size (0x80) */
1478 + agnx_write32(ctl, AGNX_BM_FPLHP, AGNX_PDU_FREE/PDU_SIZE);
1479 + /* Tail is Last Pool Address (0x47f80) / size (0x80) */
1480 + agnx_write32(ctl, AGNX_BM_FPLTP, 0x47f80/PDU_SIZE);
1481 + /* Count is Number of Nodes in the Pool (0xd0) */
1482 + agnx_write32(ctl, AGNX_BM_FPCNT, PDU_FREE_CNT);
1483 +
1484 + /* Start all workqueue */
1485 + agnx_write32(ctl, AGNX_BM_CIWQCTL, 0x80000);
1486 + agnx_write32(ctl, AGNX_BM_CPULWCTL, 0x80000);
1487 + agnx_write32(ctl, AGNX_BM_CPUHWCTL, 0x80000);
1488 + agnx_write32(ctl, AGNX_BM_CPUTXWCTL, 0x80000);
1489 + agnx_write32(ctl, AGNX_BM_CPURXWCTL, 0x80000);
1490 + agnx_write32(ctl, AGNX_BM_SPRXWCTL, 0x80000);
1491 + agnx_write32(ctl, AGNX_BM_SPTXWCTL, 0x80000);
1492 + agnx_write32(ctl, AGNX_BM_RFPWCTL, 0x80000);
1493 +
1494 + /* Enable the Band Management */
1495 + reg = agnx_read32(ctl, AGNX_BM_BMCTL);
1496 + reg |= 0x1;
1497 + agnx_write32(ctl, AGNX_BM_BMCTL, reg);
1498 +} /* band_managment_init */
1499 +
1500 +
1501 +static void system_itf_init(struct agnx_priv *priv)
1502 +{
1503 + void __iomem *ctl = priv->ctl;
1504 + u32 reg;
1505 + AGNX_TRACE;
1506 +
1507 + agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x0);
1508 + agnx_write32(ctl, AGNX_PM_TESTPHY, 0x11e143a);
1509 +
1510 + if (priv->revid == 0) {
1511 + reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE);
1512 + reg |= 0x11;
1513 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg);
1514 + }
1515 + /* ??? What is that means? it should difference for differice type
1516 + of cards */
1517 + agnx_write32(ctl, AGNX_CIR_SERIALITF, 0xfff81006);
1518 +
1519 + agnx_write32(ctl, AGNX_SYSITF_GPIOIN, 0x1f0000);
1520 + agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
1521 + reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN);
1522 +}
1523 +
1524 +static void encryption_init(struct agnx_priv *priv)
1525 +{
1526 + void __iomem *ctl = priv->ctl;
1527 + AGNX_TRACE;
1528 +
1529 + agnx_write32(ctl, AGNX_ENCRY_WEPKEY0, 0x0);
1530 + agnx_write32(ctl, AGNX_ENCRY_WEPKEY1, 0x0);
1531 + agnx_write32(ctl, AGNX_ENCRY_WEPKEY2, 0x0);
1532 + agnx_write32(ctl, AGNX_ENCRY_WEPKEY3, 0x0);
1533 + agnx_write32(ctl, AGNX_ENCRY_CCMRECTL, 0x8);
1534 +}
1535 +
1536 +static void tx_management_init(struct agnx_priv *priv)
1537 +{
1538 + void __iomem *ctl = priv->ctl;
1539 + void __iomem *data = priv->data;
1540 + u32 reg;
1541 + AGNX_TRACE;
1542 +
1543 + /* Fill out the ComputationalEngineLookupTable
1544 + * starting at memory #2 offset 0x800
1545 + */
1546 + tx_engine_lookup_tbl_init(priv);
1547 + memset_io(data + 0x1000, 0, 0xfe0);
1548 + /* Enable Transmission Management Functions */
1549 + agnx_write32(ctl, AGNX_TXM_ETMF, 0x3ff);
1550 + /* Write 0x3f to Transmission Template */
1551 + agnx_write32(ctl, AGNX_TXM_TXTEMP, 0x3f);
1552 +
1553 + if (priv->revid >= 2)
1554 + agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e140a0b);
1555 + else
1556 + agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e190a0b);
1557 +
1558 + reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
1559 + reg &= 0xff00;
1560 + reg |= 0xb;
1561 + agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
1562 + reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
1563 + reg &= 0xffff00ff;
1564 + reg |= 0xa00;
1565 + agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
1566 + /* Enable TIFS */
1567 + agnx_write32(ctl, AGNX_TXM_CTL, 0x40000);
1568 +
1569 + reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
1570 + reg &= 0xff00ffff;
1571 + reg |= 0x510000;
1572 + agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
1573 + reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
1574 + reg &= 0xff00ffff;
1575 + agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
1576 + reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
1577 + reg &= 0x00ffffff;
1578 + reg |= 0x1c000000;
1579 + agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
1580 + reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
1581 + reg &= 0x00ffffff;
1582 + reg |= 0x01000000;
1583 + agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
1584 +
1585 + /* # Set DIF 0-1,2-3,4-5,6-7 to defaults */
1586 + agnx_write32(ctl, AGNX_TXM_DIF01, 0x321d321d);
1587 + agnx_write32(ctl, AGNX_TXM_DIF23, 0x321d321d);
1588 + agnx_write32(ctl, AGNX_TXM_DIF45, 0x321d321d);
1589 + agnx_write32(ctl, AGNX_TXM_DIF67, 0x321d321d);
1590 +
1591 + /* Max Ack timeout limit */
1592 + agnx_write32(ctl, AGNX_TXM_MAXACKTIM, 0x1e19);
1593 + /* Max RX Data Timeout count, */
1594 + reg = agnx_read32(ctl, AGNX_TXM_MAXRXTIME);
1595 + reg &= 0xffff0000;
1596 + reg |= 0xff;
1597 + agnx_write32(ctl, AGNX_TXM_MAXRXTIME, reg);
1598 +
1599 + /* CF poll RX Timeout count */
1600 + reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
1601 + reg &= 0xffff;
1602 + reg |= 0xff0000;
1603 + agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
1604 +
1605 + /* Max Timeout Exceeded count, */
1606 + reg = agnx_read32(ctl, AGNX_TXM_MAXTIMOUT);
1607 + reg &= 0xff00ffff;
1608 + reg |= 0x190000;
1609 + agnx_write32(ctl, AGNX_TXM_MAXTIMOUT, reg);
1610 +
1611 + /* CF ack timeout limit for 11b */
1612 + reg = agnx_read32(ctl, AGNX_TXM_CFACKT11B);
1613 + reg &= 0xff00;
1614 + reg |= 0x1e;
1615 + agnx_write32(ctl, AGNX_TXM_CFACKT11B, reg);
1616 +
1617 + /* Max CF Poll Timeout Count */
1618 + reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
1619 + reg &= 0xffff0000;
1620 + reg |= 0x19;
1621 + agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
1622 + /* CF Poll RX Timeout Count */
1623 + reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
1624 + reg &= 0xffff0000;
1625 + reg |= 0x1e;
1626 + agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
1627 +
1628 + /* # write default to */
1629 + /* 1. Schedule Empty Count */
1630 + agnx_write32(ctl, AGNX_TXM_SCHEMPCNT, 0x5);
1631 + /* 2. CFP Period Count */
1632 + agnx_write32(ctl, AGNX_TXM_CFPERCNT, 0x1);
1633 + /* 3. CFP MDV */
1634 + agnx_write32(ctl, AGNX_TXM_CFPMDV, 0x10000);
1635 +
1636 + /* Probe Delay */
1637 + reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
1638 + reg &= 0xffff0000;
1639 + reg |= 0x400;
1640 + agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
1641 +
1642 + /* Max CCA count Slot */
1643 + reg = agnx_read32(ctl, AGNX_TXM_MAXCCACNTSLOT);
1644 + reg &= 0xffff00ff;
1645 + reg |= 0x900;
1646 + agnx_write32(ctl, AGNX_TXM_MAXCCACNTSLOT, reg);
1647 +
1648 + /* Slot limit/1 msec Limit */
1649 + reg = agnx_read32(ctl, AGNX_TXM_SLOTLIMIT);
1650 + reg &= 0xff00ffff;
1651 + reg |= 0x140077;
1652 + agnx_write32(ctl, AGNX_TXM_SLOTLIMIT, reg);
1653 +
1654 + /* # Set CW #(0-7) to default */
1655 + agnx_write32(ctl, AGNX_TXM_CW0, 0xff0007);
1656 + agnx_write32(ctl, AGNX_TXM_CW1, 0xff0007);
1657 + agnx_write32(ctl, AGNX_TXM_CW2, 0xff0007);
1658 + agnx_write32(ctl, AGNX_TXM_CW3, 0xff0007);
1659 + agnx_write32(ctl, AGNX_TXM_CW4, 0xff0007);
1660 + agnx_write32(ctl, AGNX_TXM_CW5, 0xff0007);
1661 + agnx_write32(ctl, AGNX_TXM_CW6, 0xff0007);
1662 + agnx_write32(ctl, AGNX_TXM_CW7, 0xff0007);
1663 +
1664 + /* # Set Short/Long limit #(0-7) to default */
1665 + agnx_write32(ctl, AGNX_TXM_SLBEALIM0, 0xa000a);
1666 + agnx_write32(ctl, AGNX_TXM_SLBEALIM1, 0xa000a);
1667 + agnx_write32(ctl, AGNX_TXM_SLBEALIM2, 0xa000a);
1668 + agnx_write32(ctl, AGNX_TXM_SLBEALIM3, 0xa000a);
1669 + agnx_write32(ctl, AGNX_TXM_SLBEALIM4, 0xa000a);
1670 + agnx_write32(ctl, AGNX_TXM_SLBEALIM5, 0xa000a);
1671 + agnx_write32(ctl, AGNX_TXM_SLBEALIM6, 0xa000a);
1672 + agnx_write32(ctl, AGNX_TXM_SLBEALIM7, 0xa000a);
1673 +
1674 + reg = agnx_read32(ctl, AGNX_TXM_CTL);
1675 + reg |= 0x1400;
1676 + agnx_write32(ctl, AGNX_TXM_CTL, reg);
1677 + /* Wait for bit 0 in Control Reg to clear */
1678 + udelay(80);
1679 + reg = agnx_read32(ctl, AGNX_TXM_CTL);
1680 + /* Or 0x18000 to Control reg */
1681 + reg = agnx_read32(ctl, AGNX_TXM_CTL);
1682 + reg |= 0x18000;
1683 + agnx_write32(ctl, AGNX_TXM_CTL, reg);
1684 + /* Wait for bit 0 in Control Reg to clear */
1685 + udelay(80);
1686 + reg = agnx_read32(ctl, AGNX_TXM_CTL);
1687 +
1688 + /* Set Listen Interval Count to default */
1689 + agnx_write32(ctl, AGNX_TXM_LISINTERCNT, 0x1);
1690 + /* Set DTIM period count to default */
1691 + agnx_write32(ctl, AGNX_TXM_DTIMPERICNT, 0x2000);
1692 +} /* tx_management_init */
1693 +
1694 +static void rx_management_init(struct agnx_priv *priv)
1695 +{
1696 + void __iomem *ctl = priv->ctl;
1697 + AGNX_TRACE;
1698 +
1699 + /* Initialize the Routing Table */
1700 + routing_table_init(priv);
1701 +
1702 + if (priv->revid >= 3) {
1703 + agnx_write32(ctl, 0x2074, 0x1f171710);
1704 + agnx_write32(ctl, 0x2078, 0x10100d0d);
1705 + agnx_write32(ctl, 0x207c, 0x11111010);
1706 + }
1707 + else
1708 + agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0);
1709 + agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00);
1710 +}
1711 +
1712 +
1713 +static void agnx_timer_init(struct agnx_priv *priv)
1714 +{
1715 + void __iomem *ctl = priv->ctl;
1716 + AGNX_TRACE;
1717 +
1718 +/* /\* Write 0x249f00 (tick duration?) to Timer 1 *\/ */
1719 +/* agnx_write32(ctl, AGNX_TIMCTL_TIMER1, 0x249f00); */
1720 +/* /\* Write 0xe2 to Timer 1 Control *\/ */
1721 +/* agnx_write32(ctl, AGNX_TIMCTL_TIM1CTL, 0xe2); */
1722 +
1723 + /* Write 0x249f00 (tick duration?) to Timer 1 */
1724 + agnx_write32(ctl, AGNX_TIMCTL_TIMER1, 0x0);
1725 + /* Write 0xe2 to Timer 1 Control */
1726 + agnx_write32(ctl, AGNX_TIMCTL_TIM1CTL, 0x0);
1727 +
1728 + iowrite32(0xFFFFFFFF, priv->ctl + AGNX_TXM_BEACON_CTL);
1729 +}
1730 +
1731 +static void power_manage_init(struct agnx_priv *priv)
1732 +{
1733 + void __iomem *ctl = priv->ctl;
1734 + u32 reg;
1735 + AGNX_TRACE;
1736 +
1737 + agnx_write32(ctl, AGNX_PM_MACMSW, 0x1f);
1738 + agnx_write32(ctl, AGNX_PM_RFCTL, 0x1f);
1739 +
1740 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
1741 + reg &= 0xf00f;
1742 + reg |= 0xa0;
1743 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
1744 +
1745 + if (priv->revid >= 3) {
1746 + reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
1747 + reg |= 0x18;
1748 + agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
1749 + }
1750 +} /* power_manage_init */
1751 +
1752 +
1753 +static void gain_ctlcnt_init(struct agnx_priv *priv)
1754 +{
1755 + void __iomem *ctl = priv->ctl;
1756 + u32 reg;
1757 + AGNX_TRACE;
1758 +
1759 + agnx_write32(ctl, AGNX_GCR_TRACNT5, 0x119);
1760 + agnx_write32(ctl, AGNX_GCR_TRACNT6, 0x118);
1761 + agnx_write32(ctl, AGNX_GCR_TRACNT7, 0x117);
1762 +
1763 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
1764 + reg |= 0x8;
1765 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
1766 +
1767 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
1768 + reg &= ~0x8;
1769 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
1770 +
1771 + agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0);
1772 +
1773 + /* FIXME Write the initial Station Descriptor for the card */
1774 + sta_init(priv, LOCAL_STAID);
1775 + sta_init(priv, BSSID_STAID);
1776 +
1777 + /* Enable staion 0 and 1 can do TX */
1778 + /* It seemed if we set other bit to 1 the bit 0 will
1779 + be auto change to 0 */
1780 + agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x2 | 0x1);
1781 +// agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1);
1782 +} /* gain_ctlcnt_init */
1783 +
1784 +
1785 +static void phy_init(struct agnx_priv *priv)
1786 +{
1787 + void __iomem *ctl = priv->ctl;
1788 + void __iomem *data = priv->data;
1789 + u32 reg;
1790 + AGNX_TRACE;
1791 +
1792 + /* Load InitialGainTable */
1793 + gain_table_init(priv);
1794 +
1795 + agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
1796 +
1797 + /* Clear the following offsets in Memory Range #2: */
1798 + memset_io(data + 0x5040, 0, 0xa * 4);
1799 + memset_io(data + 0x5080, 0, 0xa * 4);
1800 + memset_io(data + 0x50c0, 0, 0xa * 4);
1801 + memset_io(data + 0x5400, 0, 0x80 * 4);
1802 + memset_io(data + 0x6000, 0, 0x280 * 4);
1803 + memset_io(data + 0x7000, 0, 0x280 * 4);
1804 + memset_io(data + 0x8000, 0, 0x280 * 4);
1805 +
1806 + /* Initialize the Following Registers According to PCI Revision ID */
1807 + if (priv->revid == 0) {
1808 + /* fixme the part hasn't been update but below has been update
1809 + based on WGM511 */
1810 + agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
1811 + agnx_write32(ctl, AGNX_ACI_TIMER1, 0x1d);
1812 + agnx_write32(ctl, AGNX_ACI_TIMER2, 0x3);
1813 + agnx_write32(ctl, AGNX_ACI_AICCHA0OVE, 0x11);
1814 + agnx_write32(ctl, AGNX_ACI_AICCHA1OVE, 0x0);
1815 + agnx_write32(ctl, AGNX_GCR_THD0A, 0x64);
1816 + agnx_write32(ctl, AGNX_GCR_THD0AL, 0x4b);
1817 + agnx_write32(ctl, AGNX_GCR_THD0B, 0x4b);
1818 + agnx_write32(ctl, AGNX_GCR_DUNSAT, 0x14);
1819 + agnx_write32(ctl, AGNX_GCR_DSAT, 0x24);
1820 + agnx_write32(ctl, AGNX_GCR_DFIRCAL, 0x8);
1821 + agnx_write32(ctl, AGNX_GCR_DGCTL11A, 0x1a);
1822 + agnx_write32(ctl, AGNX_GCR_DGCTL11B, 0x3);
1823 + agnx_write32(ctl, AGNX_GCR_GAININIT, 0xd);
1824 + agnx_write32(ctl, AGNX_GCR_THNOSIG, 0x1);
1825 + agnx_write32(ctl, AGNX_GCR_COARSTEP, 0x7);
1826 + agnx_write32(ctl, AGNX_GCR_SIFST11A, 0x28);
1827 + agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
1828 + reg = agnx_read32(ctl, AGNX_GCR_CWDETEC);
1829 + reg |= 0x1;
1830 + agnx_write32(ctl, AGNX_GCR_CWDETEC, reg);
1831 + agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
1832 + agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);
1833 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
1834 + agnx_write32(ctl, AGNX_GCR_NLISTANT, 0x3);
1835 + agnx_write32(ctl, AGNX_GCR_NACTIANT, 0x3);
1836 + agnx_write32(ctl, AGNX_GCR_NMEASANT, 0x3);
1837 + agnx_write32(ctl, AGNX_GCR_NCAPTANT, 0x3);
1838 + agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x0);
1839 + agnx_write32(ctl, AGNX_GCR_THCAP11B, 0x0);
1840 + agnx_write32(ctl, AGNX_GCR_THCAPRX11A, 0x0);
1841 + agnx_write32(ctl, AGNX_GCR_THCAPRX11B, 0x0);
1842 + agnx_write32(ctl, AGNX_GCR_THLEVDRO, 0x10);
1843 + agnx_write32(ctl, AGNX_GCR_MAXRXTIME11A, 0x1);
1844 + agnx_write32(ctl, AGNX_GCR_MAXRXTIME11B, 0x1);
1845 + agnx_write32(ctl, AGNX_GCR_CORRTIME, 0x190);
1846 + agnx_write32(ctl, AGNX_GCR_SIGHTH, 0x78);
1847 + agnx_write32(ctl, AGNX_GCR_SIGLTH, 0x1c);
1848 + agnx_write32(ctl, AGNX_GCR_CORRDROP, 0x0);
1849 + agnx_write32(ctl, AGNX_GCR_THCD, 0x0);
1850 + agnx_write32(ctl, AGNX_GCR_MAXPOWDIFF, 0x1);
1851 + agnx_write32(ctl, AGNX_GCR_TESTBUS, 0x0);
1852 + agnx_write32(ctl, AGNX_GCR_ANTCFG, 0x1f);
1853 + agnx_write32(ctl, AGNX_GCR_THJUMP, 0x14);
1854 + agnx_write32(ctl, AGNX_GCR_THPOWER, 0x0);
1855 + agnx_write32(ctl, AGNX_GCR_THPOWCLIP, 0x30);
1856 + agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x32);
1857 + agnx_write32(ctl, AGNX_GCR_THRX11BPOWMIN, 0x19);
1858 + agnx_write32(ctl, AGNX_GCR_0X14c, 0x0);
1859 + agnx_write32(ctl, AGNX_GCR_0X150, 0x0);
1860 + agnx_write32(ctl, 0x9400, 0x0);
1861 + agnx_write32(ctl, 0x940c, 0x6ff);
1862 + agnx_write32(ctl, 0x9428, 0xa0);
1863 + agnx_write32(ctl, 0x9434, 0x0);
1864 + agnx_write32(ctl, 0x9c04, 0x15);
1865 + agnx_write32(ctl, 0x9c0c, 0x7f);
1866 + agnx_write32(ctl, 0x9c34, 0x0);
1867 + agnx_write32(ctl, 0xc000, 0x38d);
1868 + agnx_write32(ctl, 0x14018, 0x0);
1869 + agnx_write32(ctl, 0x16000, 0x1);
1870 + agnx_write32(ctl, 0x11004, 0x0);
1871 + agnx_write32(ctl, 0xec54, 0xa);
1872 + agnx_write32(ctl, 0xec1c, 0x5);
1873 + } else if (priv->revid > 0) {
1874 + agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
1875 + agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21);
1876 + agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
1877 + agnx_write32(ctl, AGNX_ACI_AICCHA0OVE, 0x11);
1878 + agnx_write32(ctl, AGNX_ACI_AICCHA1OVE, 0x0);
1879 + agnx_write32(ctl, AGNX_GCR_DUNSAT, 0x14);
1880 + agnx_write32(ctl, AGNX_GCR_DSAT, 0x24);
1881 + agnx_write32(ctl, AGNX_GCR_DFIRCAL, 0x8);
1882 + agnx_write32(ctl, AGNX_GCR_DGCTL11A, 0x1a);
1883 + agnx_write32(ctl, AGNX_GCR_DGCTL11B, 0x3);
1884 + agnx_write32(ctl, AGNX_GCR_GAININIT, 0xd);
1885 + agnx_write32(ctl, AGNX_GCR_THNOSIG, 0x1);
1886 + agnx_write32(ctl, AGNX_GCR_COARSTEP, 0x7);
1887 + agnx_write32(ctl, AGNX_GCR_SIFST11A, 0x28);
1888 + agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
1889 + agnx_write32(ctl, AGNX_GCR_CWDETEC, 0x0);
1890 + agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
1891 +// agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);
1892 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
1893 +
1894 + agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x32);
1895 + agnx_write32(ctl, AGNX_GCR_THCAP11B, 0x32);
1896 + agnx_write32(ctl, AGNX_GCR_THCAPRX11A, 0x32);
1897 + agnx_write32(ctl, AGNX_GCR_THCAPRX11B, 0x32);
1898 + agnx_write32(ctl, AGNX_GCR_THLEVDRO, 0x10);
1899 + agnx_write32(ctl, AGNX_GCR_MAXRXTIME11A, 0x1ad);
1900 + agnx_write32(ctl, AGNX_GCR_MAXRXTIME11B, 0xa10);
1901 + agnx_write32(ctl, AGNX_GCR_CORRTIME, 0x190);
1902 + agnx_write32(ctl, AGNX_GCR_CORRDROP, 0x0);
1903 + agnx_write32(ctl, AGNX_GCR_THCD, 0x0);
1904 + agnx_write32(ctl, AGNX_GCR_THCS, 0x0);
1905 + agnx_write32(ctl, AGNX_GCR_MAXPOWDIFF, 0x4);
1906 + agnx_write32(ctl, AGNX_GCR_TESTBUS, 0x0);
1907 + agnx_write32(ctl, AGNX_GCR_THJUMP, 0x1e);
1908 + agnx_write32(ctl, AGNX_GCR_THPOWER, 0x0);
1909 + agnx_write32(ctl, AGNX_GCR_THPOWCLIP, 0x2a);
1910 + agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x3c);
1911 + agnx_write32(ctl, AGNX_GCR_THRX11BPOWMIN, 0x19);
1912 + agnx_write32(ctl, AGNX_GCR_0X14c, 0x0);
1913 + agnx_write32(ctl, AGNX_GCR_0X150, 0x0);
1914 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
1915 + agnx_write32(ctl, AGNX_GCR_WATCHDOG, 0x37);
1916 + agnx_write32(ctl, 0x9400, 0x0);
1917 + agnx_write32(ctl, 0x940c, 0x6ff);
1918 + agnx_write32(ctl, 0x9428, 0xa0);
1919 + agnx_write32(ctl, 0x9434, 0x0);
1920 + agnx_write32(ctl, 0x9c04, 0x15);
1921 + agnx_write32(ctl, 0x9c0c, 0x7f);
1922 + agnx_write32(ctl, 0x9c34, 0x0);
1923 + agnx_write32(ctl, 0xc000, 0x38d);
1924 + agnx_write32(ctl, 0x14014, 0x1000);
1925 + agnx_write32(ctl, 0x14018, 0x0);
1926 + agnx_write32(ctl, 0x16000, 0x1);
1927 + agnx_write32(ctl, 0x11004, 0x0);
1928 + agnx_write32(ctl, 0xec54, 0xa);
1929 + agnx_write32(ctl, 0xec1c, 0x50);
1930 + } else if (priv->revid > 1) {
1931 + reg = agnx_read32(ctl, 0xec18);
1932 + reg |= 0x8;
1933 + agnx_write32(ctl, 0xec18, reg);
1934 + }
1935 +
1936 + /* Write the TX Fir Coefficient Table */
1937 + tx_fir_table_init(priv);
1938 +
1939 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
1940 + reg &= ~0x8;
1941 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
1942 + reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
1943 + reg |= 0x1;
1944 + agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
1945 +
1946 +/* reg = agnx_read32(ctl, 0x1a030); */
1947 +/* reg &= ~0x4; */
1948 +/* agnx_write32(ctl, 0x1a030, reg); */
1949 +
1950 + agnx_write32(ctl, AGNX_GCR_TRACNT4, 0x113);
1951 +} /* phy_init */
1952 +
1953 +static void chip_init(struct agnx_priv *priv)
1954 +{
1955 + void __iomem *ctl = priv->ctl;
1956 + u32 reg;
1957 + AGNX_TRACE;
1958 +
1959 + band_management_init(priv);
1960 +
1961 + rf_chips_init(priv);
1962 +
1963 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
1964 + reg |= 0x8;
1965 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
1966 +
1967 + /* Initialize the PHY */
1968 + phy_init(priv);
1969 +
1970 + encryption_init(priv);
1971 +
1972 + tx_management_init(priv);
1973 +
1974 + rx_management_init(priv);
1975 +
1976 + power_manage_init(priv);
1977 +
1978 + /* Initialize the Timers */
1979 + agnx_timer_init(priv);
1980 +
1981 + /* Write 0xc390bf9 to Interrupt Mask (Disable TX) */
1982 + reg = 0xc390bf9 & ~IRQ_TX_BEACON;
1983 + reg &= ~IRQ_TX_DISABLE;
1984 + agnx_write32(ctl, AGNX_INT_MASK, reg);
1985 +
1986 + reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
1987 + reg |= 0x800;
1988 + agnx_write32(ctl, AGNX_CIR_BLKCTL, reg);
1989 +
1990 + /* set it when need get multicast enable? */
1991 + agnx_write32(ctl, AGNX_BM_MTSM, 0xff);
1992 +} /* chip_init */
1993 +
1994 +
1995 +static inline void set_promis_and_managed(struct agnx_priv *priv)
1996 +{
1997 + void __iomem *ctl = priv->ctl;
1998 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2);
1999 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2);
2000 +}
2001 +static inline void set_learn_mode(struct agnx_priv *priv)
2002 +{
2003 + void __iomem *ctl = priv->ctl;
2004 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x8);
2005 +}
2006 +static inline void set_scan_mode(struct agnx_priv *priv)
2007 +{
2008 + void __iomem *ctl = priv->ctl;
2009 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x20);
2010 +}
2011 +static inline void set_promiscuous_mode(struct agnx_priv *priv)
2012 +{
2013 + void __iomem *ctl = priv->ctl;
2014 + /* agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x210);*/
2015 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10);
2016 +}
2017 +static inline void set_managed_mode(struct agnx_priv *priv)
2018 +{
2019 + void __iomem *ctl = priv->ctl;
2020 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x2);
2021 +}
2022 +static inline void set_adhoc_mode(struct agnx_priv *priv)
2023 +{
2024 + void __iomem *ctl = priv->ctl;
2025 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x0);
2026 +}
2027 +
2028 +static void unknow_register_write(struct agnx_priv *priv)
2029 +{
2030 + void __iomem *ctl = priv->ctl;
2031 +
2032 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x0, 0x3e);
2033 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x4, 0xb2);
2034 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x8, 0x140);
2035 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0xc, 0x1C0);
2036 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x10, 0x1FF);
2037 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x14, 0x1DD);
2038 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x18, 0x15F);
2039 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x1c, 0xA1);
2040 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x20, 0x3E7);
2041 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x24, 0x36B);
2042 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x28, 0x348);
2043 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x2c, 0x37D);
2044 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x30, 0x3DE);
2045 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x34, 0x36);
2046 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x38, 0x64);
2047 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x3c, 0x57);
2048 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x40, 0x23);
2049 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x44, 0x3ED);
2050 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x48, 0x3C9);
2051 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x4c, 0x3CA);
2052 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x50, 0x3E7);
2053 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x54, 0x8);
2054 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x58, 0x1F);
2055 + agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x5c, 0x1a);
2056 +}
2057 +
2058 +static void card_interface_init(struct agnx_priv *priv)
2059 +{
2060 + void __iomem *ctl = priv->ctl;
2061 + u8 bssid[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2062 + u32 reg;
2063 + unsigned int i;
2064 + AGNX_TRACE;
2065 +
2066 + might_sleep();
2067 + /* Clear RX Control and Enable RX queues */
2068 + agnx_write32(ctl, AGNX_CIR_RXCTL, 0x8);
2069 +
2070 + might_sleep();
2071 + /* Do a full reset of the card */
2072 + card_full_reset(priv);
2073 + might_sleep();
2074 +
2075 + /* Check and set Card Endianness */
2076 + reg = ioread32(priv->ctl + AGNX_CIR_ENDIAN);
2077 + /* TODO If not 0xB3B2B1B0 set to 0xB3B2B1B0 */
2078 + printk(KERN_INFO PFX "CIR_ENDIAN is %x\n", reg);
2079 +
2080 +
2081 + /* Config the eeprom */
2082 + agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x7000086);
2083 + udelay(10);
2084 + reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
2085 +
2086 +
2087 + agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033);
2088 + reg = agnx_read32(ctl, 0xec50);
2089 + reg |= 0xf;
2090 + agnx_write32(ctl, 0xec50, reg);
2091 + agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
2092 +
2093 +
2094 + reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN);
2095 + udelay(10);
2096 + reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
2097 +
2098 + /* Dump the eeprom */
2099 + do {
2100 + char eeprom[0x100000/0x100];
2101 +
2102 + for (i = 0; i < 0x100000; i += 0x100) {
2103 + agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x3000000 + i);
2104 + udelay(13);
2105 + reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
2106 + udelay(70);
2107 + reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
2108 + eeprom[i/0x100] = reg & 0xFF;
2109 + udelay(10);
2110 + }
2111 + print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom,
2112 + ARRAY_SIZE(eeprom));
2113 + } while(0);
2114 +
2115 + spi_rc_write(ctl, RF_CHIP0, 0x26);
2116 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
2117 +
2118 + /* Initialize the system interface */
2119 + system_itf_init(priv);
2120 +
2121 + might_sleep();
2122 + /* Chip Initialization (Polaris) */
2123 + chip_init(priv);
2124 + might_sleep();
2125 +
2126 + /* Calibrate the antennae */
2127 + antenna_calibrate(priv);
2128 +
2129 + reg = agnx_read32(ctl, 0xec50);
2130 + reg &= ~0x40;
2131 + agnx_write32(ctl, 0xec50, reg);
2132 + agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
2133 + agnx_write32(ctl, AGNX_PM_PLLCTL, 0x1);
2134 +
2135 + reg = agnx_read32(ctl, AGNX_BM_BMCTL);
2136 + reg |= 0x8000;
2137 + agnx_write32(ctl, AGNX_BM_BMCTL, reg);
2138 + enable_receiver(priv);
2139 + reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE);
2140 + reg |= 0x200;
2141 + agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg);
2142 + enable_receiver(priv);
2143 +
2144 + might_sleep();
2145 + /* Initialize Gain Control Counts */
2146 + gain_ctlcnt_init(priv);
2147 +
2148 + /* Write Initial Station Power Template for this station(#0) */
2149 + sta_power_init(priv, LOCAL_STAID);
2150 +
2151 + might_sleep();
2152 + /* Initialize the rx,td,tm rings, for each node in the ring */
2153 + fill_rings(priv);
2154 +
2155 + might_sleep();
2156 +
2157 +
2158 + agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033);
2159 + agnx_write32(ctl, 0xec50, 0xc);
2160 + agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
2161 +
2162 + /* FIXME Initialize the transmit control register */
2163 + agnx_write32(ctl, AGNX_TXM_CTL, 0x194c1);
2164 +
2165 + enable_receiver(priv);
2166 +
2167 + might_sleep();
2168 + /* FIXME Set the Receive Control Mac Address to card address */
2169 + mac_address_set(priv);
2170 + enable_receiver(priv);
2171 + might_sleep();
2172 +
2173 + /* Set the recieve request rate */
2174 + /* FIXME Enable the request */
2175 + /* Check packet length */
2176 + /* Set maximum packet length */
2177 +/* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
2178 +/* enable_receiver(priv); */
2179 +
2180 + /* Set the Receiver BSSID */
2181 + receiver_bssid_set(priv, bssid);
2182 +
2183 + /* FIXME Set to managed mode */
2184 + set_managed_mode(priv);
2185 +// set_promiscuous_mode(priv);
2186 +/* set_scan_mode(priv); */
2187 +/* set_learn_mode(priv); */
2188 +// set_promis_and_managed(priv);
2189 +// set_adhoc_mode(priv);
2190 +
2191 + /* Set the recieve request rate */
2192 + /* Check packet length */
2193 + agnx_write32(ctl, AGNX_RXM_REQRATE, 0x08000000);
2194 + reg = agnx_read32(ctl, AGNX_RXM_REQRATE);
2195 + /* Set maximum packet length */
2196 + reg |= 0x00195e00;
2197 + agnx_write32(ctl, AGNX_RXM_REQRATE, reg);
2198 +
2199 + /* Configure the RX and TX interrupt */
2200 + reg = ENABLE_RX_INTERRUPT | RX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE;
2201 + agnx_write32(ctl, AGNX_CIR_RXCFG, reg);
2202 + /* FIXME */
2203 + reg = ENABLE_TX_INTERRUPT | TX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE;
2204 + agnx_write32(ctl, AGNX_CIR_TXCFG, reg);
2205 +
2206 + /* Enable RX TX Interrupts */
2207 + agnx_write32(ctl, AGNX_CIR_RXCTL, 0x80);
2208 + agnx_write32(ctl, AGNX_CIR_TXMCTL, 0x80);
2209 + agnx_write32(ctl, AGNX_CIR_TXDCTL, 0x80);
2210 +
2211 + /* FIXME Set the master control interrupt in block control */
2212 + agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x800);
2213 +
2214 + /* Enable RX and TX queues */
2215 + reg = agnx_read32(ctl, AGNX_CIR_RXCTL);
2216 + reg |= 0x8;
2217 + agnx_write32(ctl, AGNX_CIR_RXCTL, reg);
2218 + reg = agnx_read32(ctl, AGNX_CIR_TXMCTL);
2219 + reg |= 0x8;
2220 + agnx_write32(ctl, AGNX_CIR_TXMCTL, reg);
2221 + reg = agnx_read32(ctl, AGNX_CIR_TXDCTL);
2222 + reg |= 0x8;
2223 + agnx_write32(ctl, AGNX_CIR_TXDCTL, reg);
2224 +
2225 + agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
2226 + /* FIXME */
2227 + /* unknow_register_write(priv); */
2228 + /* Update local card hash entry */
2229 + hash_write(priv, priv->mac_addr, LOCAL_STAID);
2230 +
2231 + might_sleep();
2232 +
2233 + /* FIXME */
2234 + agnx_set_channel(priv, 1);
2235 + might_sleep();
2236 +} /* agnx_card_interface_init */
2237 +
2238 +
2239 +void agnx_hw_init(struct agnx_priv *priv)
2240 +{
2241 + AGNX_TRACE;
2242 + might_sleep();
2243 + card_interface_init(priv);
2244 +}
2245 +
2246 +int agnx_hw_reset(struct agnx_priv *priv)
2247 +{
2248 + return card_full_reset(priv);
2249 +}
2250 +
2251 +int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len)
2252 +{
2253 + AGNX_TRACE;
2254 + return 0;
2255 +}
2256 +
2257 +void agnx_set_bssid(struct agnx_priv *priv, u8 *bssid)
2258 +{
2259 + receiver_bssid_set(priv, bssid);
2260 +}
2261 --- /dev/null
2262 +++ b/drivers/staging/agnx/phy.h
2263 @@ -0,0 +1,409 @@
2264 +#ifndef AGNX_PHY_H_
2265 +#define AGNX_PHY_H_
2266 +
2267 +#include "agnx.h"
2268 +
2269 +/* Transmission Managment Registers */
2270 +#define AGNX_TXM_BASE 0x0000
2271 +#define AGNX_TXM_CTL 0x0000 /* control register */
2272 +#define AGNX_TXM_ETMF 0x0004 /* enable transmission management functions */
2273 +#define AGNX_TXM_TXTEMP 0x0008 /* transmission template */
2274 +#define AGNX_TXM_RETRYSTAID 0x000c /* Retry Station ID */
2275 +#define AGNX_TXM_TIMESTAMPLO 0x0010 /* Timestamp Lo */
2276 +#define AGNX_TXM_TIMESTAMPHI 0x0014 /* Timestamp Hi */
2277 +#define AGNX_TXM_TXDELAY 0x0018 /* tx delay */
2278 +#define AGNX_TXM_TBTTLO 0x0020 /* tbtt Lo */
2279 +#define AGNX_TXM_TBTTHI 0x0024 /* tbtt Hi */
2280 +#define AGNX_TXM_BEAINTER 0x0028 /* Beacon Interval */
2281 +#define AGNX_TXM_NAV 0x0030 /* NAV */
2282 +#define AGNX_TXM_CFPMDV 0x0034 /* CFP MDV */
2283 +#define AGNX_TXM_CFPERCNT 0x0038 /* CFP period count */
2284 +#define AGNX_TXM_PROBDELAY 0x003c /* probe delay */
2285 +#define AGNX_TXM_LISINTERCNT 0x0040 /* listen interval count */
2286 +#define AGNX_TXM_DTIMPERICNT 0x004c /* DTIM period count */
2287 +
2288 +#define AGNX_TXM_BEACON_CTL 0x005c /* beacon control */
2289 +
2290 +#define AGNX_TXM_SCHEMPCNT 0x007c /* schedule empty count */
2291 +#define AGNX_TXM_MAXTIMOUT 0x0084 /* max timeout exceed count */
2292 +#define AGNX_TXM_MAXCFPTIM 0x0088 /* max CF poll timeout count */
2293 +#define AGNX_TXM_MAXRXTIME 0x008c /* max RX timeout count */
2294 +#define AGNX_TXM_MAXACKTIM 0x0090 /* max ACK timeout count */
2295 +#define AGNX_TXM_DIF01 0x00a0 /* DIF 0-1 */
2296 +#define AGNX_TXM_DIF23 0x00a4 /* DIF 2-3 */
2297 +#define AGNX_TXM_DIF45 0x00a8 /* DIF 4-5 */
2298 +#define AGNX_TXM_DIF67 0x00ac /* DIF 6-7 */
2299 +#define AGNX_TXM_SIFSPIFS 0x00b0 /* SIFS/PIFS */
2300 +#define AGNX_TXM_TIFSEIFS 0x00b4 /* TIFS/EIFS */
2301 +#define AGNX_TXM_MAXCCACNTSLOT 0x00b8 /* max CCA count slot */
2302 +#define AGNX_TXM_SLOTLIMIT 0x00bc /* slot limit/1 msec limit */
2303 +#define AGNX_TXM_CFPOLLRXTIM 0x00f0 /* CF poll RX timeout count */
2304 +#define AGNX_TXM_CFACKT11B 0x00f4 /* CF ack timeout limit for 11b */
2305 +#define AGNX_TXM_CW0 0x0100 /* CW 0 */
2306 +#define AGNX_TXM_SLBEALIM0 0x0108 /* short/long beacon limit 0 */
2307 +#define AGNX_TXM_CW1 0x0120 /* CW 1 */
2308 +#define AGNX_TXM_SLBEALIM1 0x0128 /* short/long beacon limit 1 */
2309 +#define AGNX_TXM_CW2 0x0140 /* CW 2 */
2310 +#define AGNX_TXM_SLBEALIM2 0x0148 /* short/long beacon limit 2 */
2311 +#define AGNX_TXM_CW3 0x0160 /* CW 3 */
2312 +#define AGNX_TXM_SLBEALIM3 0x0168 /* short/long beacon limit 3 */
2313 +#define AGNX_TXM_CW4 0x0180 /* CW 4 */
2314 +#define AGNX_TXM_SLBEALIM4 0x0188 /* short/long beacon limit 4 */
2315 +#define AGNX_TXM_CW5 0x01a0 /* CW 5 */
2316 +#define AGNX_TXM_SLBEALIM5 0x01a8 /* short/long beacon limit 5 */
2317 +#define AGNX_TXM_CW6 0x01c0 /* CW 6 */
2318 +#define AGNX_TXM_SLBEALIM6 0x01c8 /* short/long beacon limit 6 */
2319 +#define AGNX_TXM_CW7 0x01e0 /* CW 7 */
2320 +#define AGNX_TXM_SLBEALIM7 0x01e8 /* short/long beacon limit 7 */
2321 +#define AGNX_TXM_BEACONTEMP 0x1000 /* beacon template */
2322 +#define AGNX_TXM_STAPOWTEMP 0x1a00 /* Station Power Template */
2323 +
2324 +/* Receive Management Control Registers */
2325 +#define AGNX_RXM_BASE 0x2000
2326 +#define AGNX_RXM_REQRATE 0x2000 /* requested rate */
2327 +#define AGNX_RXM_MACHI 0x2004 /* first 4 bytes of mac address */
2328 +#define AGNX_RXM_MACLO 0x2008 /* last 2 bytes of mac address */
2329 +#define AGNX_RXM_BSSIDHI 0x200c /* bssid hi */
2330 +#define AGNX_RXM_BSSIDLO 0x2010 /* bssid lo */
2331 +#define AGNX_RXM_HASH_CMD_FLAG 0x2014 /* Flags for the RX Hash Command Default:0 */
2332 +#define AGNX_RXM_HASH_CMD_HIGH 0x2018 /* The High half of the Hash Command */
2333 +#define AGNX_RXM_HASH_CMD_LOW 0x201c /* The Low half of the Hash Command */
2334 +#define AGNX_RXM_ROUTAB 0x2020 /* routing table */
2335 +#define ROUTAB_SUBTYPE_SHIFT 24
2336 +#define ROUTAB_TYPE_SHIFT 28
2337 +#define ROUTAB_STATUS_SHIFT 30
2338 +#define ROUTAB_RW_SHIFT 31
2339 +#define ROUTAB_ROUTE_DROP 0xf00000 /* Drop */
2340 +#define ROUTAB_ROUTE_CPU 0x400000 /* CPU */
2341 +#define ROUTAB_ROUTE_ENCRY 0x500800 /* Encryption */
2342 +#define ROUTAB_ROUTE_RFP 0x800000 /* RFP */
2343 +
2344 +#define ROUTAB_TYPE_MANAG 0x0 /* Management */
2345 +#define ROUTAB_TYPE_CTL 0x1 /* Control */
2346 +#define ROUTAB_TYPE_DATA 0x2 /* Data */
2347 +
2348 +#define ROUTAB_SUBTYPE_DATA 0x0
2349 +#define ROUTAB_SUBTYPE_DATAACK 0x1
2350 +#define ROUTAB_SUBTYPE_DATAPOLL 0x2
2351 +#define ROUTAB_SUBTYPE_DATAPOLLACK 0x3
2352 +#define ROUTAB_SUBTYPE_NULL 0x4 /* NULL */
2353 +#define ROUTAB_SUBTYPE_NULLACK 0x5
2354 +#define ROUTAB_SUBTYPE_NULLPOLL 0x6
2355 +#define ROUTAB_SUBTYPE_NULLPOLLACK 0x7
2356 +#define ROUTAB_SUBTYPE_QOSDATA 0x8 /* QOS DATA */
2357 +#define ROUTAB_SUBTYPE_QOSDATAACK 0x9
2358 +#define ROUTAB_SUBTYPE_QOSDATAPOLL 0xa
2359 +#define ROUTAB_SUBTYPE_QOSDATAACKPOLL 0xb
2360 +#define ROUTAB_SUBTYPE_QOSNULL 0xc
2361 +#define ROUTAB_SUBTYPE_QOSNULLACK 0xd
2362 +#define ROUTAB_SUBTYPE_QOSNULLPOLL 0xe
2363 +#define ROUTAB_SUBTYPE_QOSNULLPOLLACK 0xf
2364 +#define AGNX_RXM_DELAY11 0x2024 /* delay 11(AB) */
2365 +#define AGNX_RXM_SOF_CNT 0x2028 /* SOF Count */
2366 +#define AGNX_RXM_FRAG_CNT 0x202c /* Fragment Count*/
2367 +#define AGNX_RXM_FCS_CNT 0x2030 /* FCS Count */
2368 +#define AGNX_RXM_BSSID_MISS_CNT 0x2034 /* BSSID Miss Count */
2369 +#define AGNX_RXM_PDU_ERR_CNT 0x2038 /* PDU Error Count */
2370 +#define AGNX_RXM_DEST_MISS_CNT 0x203C /* Destination Miss Count */
2371 +#define AGNX_RXM_DROP_CNT 0x2040 /* Drop Count */
2372 +#define AGNX_RXM_ABORT_CNT 0x2044 /* Abort Count */
2373 +#define AGNX_RXM_RELAY_CNT 0x2048 /* Relay Count */
2374 +#define AGNX_RXM_HASH_MISS_CNT 0x204c /* Hash Miss Count */
2375 +#define AGNX_RXM_SA_HI 0x2050 /* Address of received packet Hi */
2376 +#define AGNX_RXM_SA_LO 0x2054 /* Address of received packet Lo */
2377 +#define AGNX_RXM_HASH_DUMP_LST 0x2100 /* Contains Hash Data */
2378 +#define AGNX_RXM_HASH_DUMP_MST 0x2104 /* Contains Hash Data */
2379 +#define AGNX_RXM_HASH_DUMP_DATA 0x2108 /* The Station ID to dump */
2380 +
2381 +
2382 +/* Encryption Managment */
2383 +#define AGNX_ENCRY_BASE 0x2400
2384 +#define AGNX_ENCRY_WEPKEY0 0x2440 /* wep key #0 */
2385 +#define AGNX_ENCRY_WEPKEY1 0x2444 /* wep key #1 */
2386 +#define AGNX_ENCRY_WEPKEY2 0x2448 /* wep key #2 */
2387 +#define AGNX_ENCRY_WEPKEY3 0x244c /* wep key #3 */
2388 +#define AGNX_ENCRY_CCMRECTL 0x2460 /* ccm replay control */
2389 +
2390 +
2391 +/* Band Management Registers */
2392 +#define AGNX_BM_BASE 0x2c00
2393 +#define AGNX_BM_BMCTL 0x2c00 /* band management control */
2394 +#define AGNX_BM_TXWADDR 0x2c18 /* tx workqueue address start */
2395 +#define AGNX_BM_TXTOPEER 0x2c24 /* transmit to peers */
2396 +#define AGNX_BM_FPLHP 0x2c2c /* free pool list head pointer */
2397 +#define AGNX_BM_FPLTP 0x2c30 /* free pool list tail pointer */
2398 +#define AGNX_BM_FPCNT 0x2c34 /* free pool count */
2399 +#define AGNX_BM_CIPDUWCNT 0x2c38 /* card interface pdu workqueue count */
2400 +#define AGNX_BM_SPPDUWCNT 0x2c3c /* sp pdu workqueue count */
2401 +#define AGNX_BM_RFPPDUWCNT 0x2c40 /* rfp pdu workqueue count */
2402 +#define AGNX_BM_RHPPDUWCNT 0x2c44 /* rhp pdu workqueue count */
2403 +#define AGNX_BM_CIWQCTL 0x2c48 /* Card Interface WorkQueue Control */
2404 +#define AGNX_BM_CPUTXWCTL 0x2c50 /* cpu tx workqueue control */
2405 +#define AGNX_BM_CPURXWCTL 0x2c58 /* cpu rx workqueue control */
2406 +#define AGNX_BM_CPULWCTL 0x2c60 /* cpu low workqueue control */
2407 +#define AGNX_BM_CPUHWCTL 0x2c68 /* cpu high workqueue control */
2408 +#define AGNX_BM_SPTXWCTL 0x2c70 /* sp tx workqueue control */
2409 +#define AGNX_BM_SPRXWCTL 0x2c78 /* sp rx workqueue control */
2410 +#define AGNX_BM_RFPWCTL 0x2c80 /* RFP workqueue control */
2411 +#define AGNX_BM_MTSM 0x2c90 /* Multicast Transmit Station Mask */
2412 +
2413 +/* Card Interface Registers (32bits) */
2414 +#define AGNX_CIR_BASE 0x3000
2415 +#define AGNX_CIR_BLKCTL 0x3000 /* block control*/
2416 +#define AGNX_STAT_TX 0x1
2417 +#define AGNX_STAT_RX 0x2
2418 +#define AGNX_STAT_X 0x4
2419 +/* Below two interrupt flags will be set by our but not CPU or the card */
2420 +#define AGNX_STAT_TXD 0x10
2421 +#define AGNX_STAT_TXM 0x20
2422 +
2423 +#define AGNX_CIR_ADDRWIN 0x3004 /* Addressable Windows*/
2424 +#define AGNX_CIR_ENDIAN 0x3008 /* card endianness */
2425 +#define AGNX_CIR_SERIALITF 0x3020 /* serial interface */
2426 +#define AGNX_CIR_RXCFG 0x3040 /* receive config */
2427 +#define ENABLE_RX_INTERRUPT 0x20
2428 +#define RX_CACHE_LINE 0x8
2429 +/* the RX fragment length */
2430 +#define FRAG_LEN_256 0x0 /* 256B */
2431 +#define FRAG_LEN_512 0x1
2432 +#define FRAG_LEN_1024 0x2
2433 +#define FRAG_LEN_2048 0x3
2434 +#define FRAG_BE 0x10
2435 +#define AGNX_CIR_RXCTL 0x3050 /* receive control */
2436 +/* memory address, chipside */
2437 +#define AGNX_CIR_RXCMSTART 0x3054 /* receive client memory start */
2438 +#define AGNX_CIR_RXCMEND 0x3058 /* receive client memory end */
2439 +/* memory address, pci */
2440 +#define AGNX_CIR_RXHOSTADDR 0x3060 /* receive hostside address */
2441 +/* memory address, chipside */
2442 +#define AGNX_CIR_RXCLIADDR 0x3064 /* receive clientside address */
2443 +#define AGNX_CIR_RXDMACTL 0x3068 /* receive dma control */
2444 +#define AGNX_CIR_TXCFG 0x3080 /* transmit config */
2445 +#define AGNX_CIR_TXMCTL 0x3090 /* Transmit Management Control */
2446 +#define ENABLE_TX_INTERRUPT 0x20
2447 +#define TX_CACHE_LINE 0x8
2448 +#define AGNX_CIR_TXMSTART 0x3094 /* Transmit Management Start */
2449 +#define AGNX_CIR_TXMEND 0x3098 /* Transmit Management End */
2450 +#define AGNX_CIR_TXDCTL 0x30a0 /* transmit data control */
2451 +/* memeory address, chipset */
2452 +#define AGNX_CIR_TXDSTART 0x30a4 /* transmit data start */
2453 +#define AGNX_CIR_TXDEND 0x30a8 /* transmit data end */
2454 +#define AGNX_CIR_TXMHADDR 0x30b0 /* Transmit Management Hostside Address */
2455 +#define AGNX_CIR_TXMCADDR 0x30b4 /* Transmit Management Clientside Address */
2456 +#define AGNX_CIR_TXDMACTL 0x30b8 /* transmit dma control */
2457 +
2458 +
2459 +/* Power Managment Unit */
2460 +#define AGNX_PM_BASE 0x3c00
2461 +#define AGNX_PM_PMCTL 0x3c00 /* PM Control*/
2462 +#define AGNX_PM_MACMSW 0x3c08 /* MAC Manual Slow Work Enable */
2463 +#define AGNX_PM_RFCTL 0x3c0c /* RF Control */
2464 +#define AGNX_PM_PHYMW 0x3c14 /* Phy Mannal Work */
2465 +#define AGNX_PM_SOFTRST 0x3c18 /* PMU Soft Reset */
2466 +#define AGNX_PM_PLLCTL 0x3c1c /* PMU PLL control*/
2467 +#define AGNX_PM_TESTPHY 0x3c24 /* PMU Test Phy */
2468 +
2469 +
2470 +/* Interrupt Control interface */
2471 +#define AGNX_INT_BASE 0x4000
2472 +#define AGNX_INT_STAT 0x4000 /* interrupt status */
2473 +#define AGNX_INT_MASK 0x400c /* interrupt mask */
2474 +/* FIXME */
2475 +#define IRQ_TX_BEACON 0x1 /* TX Beacon */
2476 +#define IRQ_TX_RETRY 0x8 /* TX Retry Interrupt */
2477 +#define IRQ_TX_ACTIVITY 0x10 /* TX Activity */
2478 +#define IRQ_RX_ACTIVITY 0x20 /* RX Activity */
2479 +/* FIXME I guess that instead RX a none exist staion's packet or
2480 + the station hasn't been init */
2481 +#define IRQ_RX_X 0x40
2482 +#define IRQ_RX_Y 0x80 /* RX ? */
2483 +#define IRQ_RX_HASHHIT 0x100 /* RX Hash Hit */
2484 +#define IRQ_RX_FRAME 0x200 /* RX Frame */
2485 +#define IRQ_ERR_INT 0x400 /* Error Interrupt */
2486 +#define IRQ_TX_QUE_FULL 0x800 /* TX Workqueue Full */
2487 +#define IRQ_BANDMAN_ERR 0x10000 /* Bandwidth Management Error */
2488 +#define IRQ_TX_DISABLE 0x20000 /* TX Disable */
2489 +#define IRQ_RX_IVASESKEY 0x80000 /* RX Invalid Session Key */
2490 +#define IRQ_RX_KEYIDMIS 0x100000 /* RX key ID Mismatch */
2491 +#define IRQ_REP_THHIT 0x200000 /* Replay Threshold Hit */
2492 +#define IRQ_TIMER1 0x4000000 /* Timer1 */
2493 +#define IRQ_TIMER_CNT 0x10000000 /* Timer Count */
2494 +#define IRQ_PHY_FASTINT 0x20000000 /* Phy Fast Interrupt */
2495 +#define IRQ_PHY_SLOWINT 0x40000000 /* Phy Slow Interrupt */
2496 +#define IRQ_OTHER 0x80000000 /* Unknow interrupt */
2497 +#define AGNX_IRQ_ALL 0xffffffff
2498 +
2499 +/* System Interface */
2500 +#define AGNX_SYSITF_BASE 0x4400
2501 +#define AGNX_SYSITF_SYSMODE 0x4400 /* system mode */
2502 +#define AGNX_SYSITF_GPIOIN 0x4410 /* GPIO In */
2503 +/* PIN lines for leds? */
2504 +#define AGNX_SYSITF_GPIOUT 0x4414 /* GPIO Out */
2505 +
2506 +/* Timer Control */
2507 +#define AGNX_TIMCTL_TIMER1 0x4800 /* Timer 1 */
2508 +#define AGNX_TIMCTL_TIM1CTL 0x4808 /* Timer 1 Control */
2509 +
2510 +
2511 +/* Antenna Calibration Interface */
2512 +#define AGNX_ACI_BASE 0x5000
2513 +#define AGNX_ACI_MODE 0x5000 /* Mode */
2514 +#define AGNX_ACI_MEASURE 0x5004 /* Measure */
2515 +#define AGNX_ACI_SELCHAIN 0x5008 /* Select Chain */
2516 +#define AGNX_ACI_LEN 0x500c /* Length */
2517 +#define AGNX_ACI_TIMER1 0x5018 /* Timer 1 */
2518 +#define AGNX_ACI_TIMER2 0x501c /* Timer 2 */
2519 +#define AGNX_ACI_OFFSET 0x5020 /* Offset */
2520 +#define AGNX_ACI_STATUS 0x5030 /* Status */
2521 +#define CALI_IDLE 0x0
2522 +#define CALI_DONE 0x1
2523 +#define CALI_BUSY 0x2
2524 +#define CALI_ERR 0x3
2525 +#define AGNX_ACI_AICCHA0OVE 0x5034 /* AIC Channel 0 Override */
2526 +#define AGNX_ACI_AICCHA1OVE 0x5038 /* AIC Channel 1 Override */
2527 +
2528 +/* Gain Control Registers */
2529 +#define AGNX_GCR_BASE 0x9000
2530 +/* threshold of primary antenna */
2531 +#define AGNX_GCR_THD0A 0x9000 /* threshold? D0 A */
2532 +/* low threshold of primary antenna */
2533 +#define AGNX_GCR_THD0AL 0x9004 /* threshold? D0 A low */
2534 +/* threshold of secondary antenna */
2535 +#define AGNX_GCR_THD0B 0x9008 /* threshold? D0_B */
2536 +#define AGNX_GCR_DUNSAT 0x900c /* d unsaturated */
2537 +#define AGNX_GCR_DSAT 0x9010 /* d saturated */
2538 +#define AGNX_GCR_DFIRCAL 0x9014 /* D Fir/Cal */
2539 +#define AGNX_GCR_DGCTL11A 0x9018 /* d gain control 11a */
2540 +#define AGNX_GCR_DGCTL11B 0x901c /* d gain control 11b */
2541 +/* strength of gain */
2542 +#define AGNX_GCR_GAININIT 0x9020 /* gain initialization */
2543 +#define AGNX_GCR_THNOSIG 0x9024 /* threhold no signal */
2544 +#define AGNX_GCR_COARSTEP 0x9028 /* coarse stepping */
2545 +#define AGNX_GCR_SIFST11A 0x902c /* sifx time 11a */
2546 +#define AGNX_GCR_SIFST11B 0x9030 /* sifx time 11b */
2547 +#define AGNX_GCR_CWDETEC 0x9034 /* cw detection */
2548 +#define AGNX_GCR_0X38 0x9038 /* ???? */
2549 +#define AGNX_GCR_BOACT 0x903c /* BO Active */
2550 +#define AGNX_GCR_BOINACT 0x9040 /* BO Inactive */
2551 +#define AGNX_GCR_BODYNA 0x9044 /* BO dynamic */
2552 +/* 802.11 mode(a,b,g) */
2553 +#define AGNX_GCR_DISCOVMOD 0x9048 /* discovery mode */
2554 +#define AGNX_GCR_NLISTANT 0x904c /* number of listening antenna */
2555 +#define AGNX_GCR_NACTIANT 0x9050 /* number of active antenna */
2556 +#define AGNX_GCR_NMEASANT 0x9054 /* number of measuring antenna */
2557 +#define AGNX_GCR_NCAPTANT 0x9058 /* number of capture antenna */
2558 +#define AGNX_GCR_THCAP11A 0x905c /* threshold capture 11a */
2559 +#define AGNX_GCR_THCAP11B 0x9060 /* threshold capture 11b */
2560 +#define AGNX_GCR_THCAPRX11A 0x9064 /* threshold capture rx 11a */
2561 +#define AGNX_GCR_THCAPRX11B 0x9068 /* threshold capture rx 11b */
2562 +#define AGNX_GCR_THLEVDRO 0x906c /* threshold level drop */
2563 +#define AGNX_GCR_GAINSET0 0x9070 /* Gainset 0 */
2564 +#define AGNX_GCR_GAINSET1 0x9074 /* Gainset 1 */
2565 +#define AGNX_GCR_GAINSET2 0x9078 /* Gainset 2 */
2566 +#define AGNX_GCR_MAXRXTIME11A 0x907c /* maximum rx time 11a */
2567 +#define AGNX_GCR_MAXRXTIME11B 0x9080 /* maximum rx time 11b */
2568 +#define AGNX_GCR_CORRTIME 0x9084 /* correction time */
2569 +/* reset the subsystem, 0 = disable, 1 = enable */
2570 +#define AGNX_GCR_RSTGCTL 0x9088 /* reset gain control */
2571 +/* channel receiving */
2572 +#define AGNX_GCR_RXCHANEL 0x908c /* receive channel */
2573 +#define AGNX_GCR_NOISE0 0x9090 /* Noise 0 */
2574 +#define AGNX_GCR_NOISE1 0x9094 /* Noise 1 */
2575 +#define AGNX_GCR_NOISE2 0x9098 /* Noise 2 */
2576 +#define AGNX_GCR_SIGHTH 0x909c /* Signal High Threshold */
2577 +#define AGNX_GCR_SIGLTH 0x90a0 /* Signal Low Threshold */
2578 +#define AGNX_GCR_CORRDROP 0x90a4 /* correction drop */
2579 +/* threshold of tertiay antenna */
2580 +#define AGNX_GCR_THCD 0x90a8 /* threshold? CD */
2581 +#define AGNX_GCR_THCS 0x90ac /* threshold? CS */
2582 +#define AGNX_GCR_MAXPOWDIFF 0x90b8 /* maximum power difference */
2583 +#define AGNX_GCR_TRACNT4 0x90ec /* Transition Count 4 */
2584 +#define AGNX_GCR_TRACNT5 0x90f0 /* transition count 5 */
2585 +#define AGNX_GCR_TRACNT6 0x90f4 /* transition count 6 */
2586 +#define AGNX_GCR_TRACNT7 0x90f8 /* transition coutn 7 */
2587 +#define AGNX_GCR_TESTBUS 0x911c /* test bus */
2588 +#define AGNX_GCR_CHAINNUM 0x9120 /* Number of Chains */
2589 +#define AGNX_GCR_ANTCFG 0x9124 /* Antenna Config */
2590 +#define AGNX_GCR_THJUMP 0x912c /* threhold jump */
2591 +#define AGNX_GCR_THPOWER 0x9130 /* threshold power */
2592 +#define AGNX_GCR_THPOWCLIP 0x9134 /* threshold power clip*/
2593 +#define AGNX_GCR_FORCECTLCLK 0x9138 /* Force Gain Control Clock */
2594 +#define AGNX_GCR_GAINSETWRITE 0x913c /* Gainset Write */
2595 +#define AGNX_GCR_THD0BTFEST 0x9140 /* threshold d0 b tf estimate */
2596 +#define AGNX_GCR_THRX11BPOWMIN 0x9144 /* threshold rx 11b power minimum */
2597 +#define AGNX_GCR_0X14c 0x914c /* ?? */
2598 +#define AGNX_GCR_0X150 0x9150 /* ?? */
2599 +#define AGNX_GCR_RXOVERIDE 0x9194 /* recieve override */
2600 +#define AGNX_GCR_WATCHDOG 0x91b0 /* watchdog timeout */
2601 +
2602 +
2603 +/* Spi Interface */
2604 +#define AGNX_SPI_BASE 0xdc00
2605 +#define AGNX_SPI_CFG 0xdc00 /* spi configuration */
2606 +/* Only accept 16 bits */
2607 +#define AGNX_SPI_WMSW 0xdc04 /* write most significant word */
2608 +/* Only accept 16 bits */
2609 +#define AGNX_SPI_WLSW 0xdc08 /* write least significant word */
2610 +#define AGNX_SPI_CTL 0xdc0c /* spi control */
2611 +#define AGNX_SPI_RMSW 0xdc10 /* read most significant word */
2612 +#define AGNX_SPI_RLSW 0xdc14 /* read least significant word */
2613 +/* SPI Control Mask */
2614 +#define SPI_READ_CTL 0x4000 /* read control */
2615 +#define SPI_BUSY_CTL 0x8000 /* busy control */
2616 +/* RF and synth chips in spi */
2617 +#define RF_CHIP0 0x400
2618 +#define RF_CHIP1 0x800
2619 +#define RF_CHIP2 0x1000
2620 +#define SYNTH_CHIP 0x2000
2621 +
2622 +/* Unknown register */
2623 +#define AGNX_UNKNOWN_BASE 0x7800
2624 +
2625 +/* FIXME MonitorGain */
2626 +#define AGNX_MONGCR_BASE 0x12000
2627 +
2628 +/* Gain Table */
2629 +#define AGNX_GAIN_TABLE 0x12400
2630 +
2631 +/* The initial FIR coefficient table */
2632 +#define AGNX_FIR_BASE 0x19804
2633 +
2634 +#define AGNX_ENGINE_LOOKUP_TBL 0x800
2635 +
2636 +/* eeprom commands */
2637 +#define EEPROM_CMD_NULL 0x0 /* NULL */
2638 +#define EEPROM_CMD_WRITE 0x2 /* write */
2639 +#define EEPROM_CMD_READ 0x3 /* read */
2640 +#define EEPROM_CMD_STATUSREAD 0x5 /* status register read */
2641 +#define EEPROM_CMD_WRITEENABLE 0x6 /* write enable */
2642 +#define EEPROM_CMD_CONFIGURE 0x7 /* configure */
2643 +
2644 +#define EEPROM_DATAFORCOFIGURE 0x6 /* ??? */
2645 +
2646 +/* eeprom address */
2647 +#define EEPROM_ADDR_SUBVID 0x0 /* Sub Vendor ID */
2648 +#define EEPROM_ADDR_SUBSID 0x2 /* Sub System ID */
2649 +#define EEPROM_ADDR_MACADDR 0x146 /* MAC Address */
2650 +#define EEPROM_ADDR_LOTYPE 0x14f /* LO type */
2651 +
2652 +struct agnx_eeprom {
2653 + u8 data; /* date */
2654 + u16 address; /* address in EEPROM */
2655 + u8 cmd; /* command, unknown, status */
2656 +} __attribute__((__packed__));
2657 +
2658 +#define AGNX_EEPROM_COMMAND_SHIFT 5
2659 +#define AGNX_EEPROM_COMMAND_STAT 0x01
2660 +
2661 +void disable_receiver(struct agnx_priv *priv);
2662 +void enable_receiver(struct agnx_priv *priv);
2663 +u8 read_from_eeprom(struct agnx_priv *priv, u16 address);
2664 +void agnx_hw_init(struct agnx_priv *priv);
2665 +int agnx_hw_reset(struct agnx_priv *priv);
2666 +int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len);
2667 +void agnx_set_bssid(struct agnx_priv *priv, u8 *bssid);
2668 +void enable_power_saving(struct agnx_priv *priv);
2669 +void disable_power_saving(struct agnx_priv *priv);
2670 +void calibrate_antenna_period(unsigned long data);
2671 +
2672 +#endif /* AGNX_PHY_H_ */
2673 --- /dev/null
2674 +++ b/drivers/staging/agnx/rf.c
2675 @@ -0,0 +1,894 @@
2676 +/**
2677 + * Airgo MIMO wireless driver
2678 + *
2679 + * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
2680 +
2681 + * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
2682 + * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
2683 +
2684 + * This program is free software; you can redistribute it and/or modify
2685 + * it under the terms of the GNU General Public License version 2 as
2686 + * published by the Free Software Foundation;
2687 + */
2688 +
2689 +#include <linux/pci.h>
2690 +#include <linux/delay.h>
2691 +#include "agnx.h"
2692 +#include "debug.h"
2693 +#include "phy.h"
2694 +#include "table.h"
2695 +
2696 +/* FIXME! */
2697 +static inline void spi_write(void __iomem *region, u32 chip_ids, u32 sw,
2698 + u16 size, u32 control)
2699 +{
2700 + u32 reg;
2701 + u32 lsw = sw & 0xffff; /* lower 16 bits of sw*/
2702 + u32 msw = sw >> 16; /* high 16 bits of sw */
2703 +
2704 + /* FIXME Write Most Significant Word of the 32bit data to MSW */
2705 + /* FIXME And Least Significant Word to LSW */
2706 + iowrite32((lsw), region + AGNX_SPI_WLSW);
2707 + iowrite32((msw), region + AGNX_SPI_WMSW);
2708 + reg = chip_ids | size | control;
2709 + /* Write chip id(s), write size and busy control to Control Register */
2710 + iowrite32((reg), region + AGNX_SPI_CTL);
2711 + /* Wait for Busy control to clear */
2712 + spi_delay();
2713 +}
2714 +
2715 +/*
2716 + * Write to SPI Synth register
2717 + */
2718 +static inline void spi_sy_write(void __iomem *region, u32 chip_ids, u32 sw)
2719 +{
2720 + /* FIXME the size 0x15 is a magic value*/
2721 + spi_write(region, chip_ids, sw, 0x15, SPI_BUSY_CTL);
2722 +}
2723 +
2724 +/*
2725 + * Write to SPI RF register
2726 + */
2727 +static inline void spi_rf_write(void __iomem *region, u32 chip_ids, u32 sw)
2728 +{
2729 + /* FIXME the size 0xd is a magic value*/
2730 + spi_write(region, chip_ids, sw, 0xd, SPI_BUSY_CTL);
2731 +} /* spi_rf_write */
2732 +
2733 +/*
2734 + * Write to SPI with Read Control bit set
2735 + */
2736 +inline void spi_rc_write(void __iomem *region, u32 chip_ids, u32 sw)
2737 +{
2738 + /* FIXME the size 0xe5 is a magic value */
2739 + spi_write(region, chip_ids, sw, 0xe5, SPI_BUSY_CTL|SPI_READ_CTL);
2740 +}
2741 +
2742 +/* Get the active chains's count */
2743 +static int get_active_chains(struct agnx_priv *priv)
2744 +{
2745 + void __iomem *ctl = priv->ctl;
2746 + int num = 0;
2747 + u32 reg;
2748 + AGNX_TRACE;
2749 +
2750 + spi_rc_write(ctl, RF_CHIP0, 0x21);
2751 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
2752 + if (reg == 1)
2753 + num++;
2754 +
2755 + spi_rc_write(ctl, RF_CHIP1, 0x21);
2756 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
2757 + if (reg == 1)
2758 + num++;
2759 +
2760 + spi_rc_write(ctl, RF_CHIP2, 0x21);
2761 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
2762 + if (reg == 1)
2763 + num++;
2764 +
2765 + spi_rc_write(ctl, RF_CHIP0, 0x26);
2766 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
2767 + if (0x33 != reg)
2768 + printk(KERN_WARNING PFX "Unmatched rf chips result\n");
2769 +
2770 + return num;
2771 +} /* get_active_chains */
2772 +
2773 +void rf_chips_init(struct agnx_priv *priv)
2774 +{
2775 + void __iomem *ctl = priv->ctl;
2776 + u32 reg;
2777 + int num;
2778 + AGNX_TRACE;
2779 +
2780 + if (priv->revid == 1) {
2781 + reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT);
2782 + reg |= 0x8;
2783 + agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg);
2784 + }
2785 +
2786 + /* Set SPI clock speed to 200NS */
2787 + reg = agnx_read32(ctl, AGNX_SPI_CFG);
2788 + reg &= ~0xF;
2789 + reg |= 0x3;
2790 + agnx_write32(ctl, AGNX_SPI_CFG, reg);
2791 +
2792 + /* Set SPI clock speed to 50NS */
2793 + reg = agnx_read32(ctl, AGNX_SPI_CFG);
2794 + reg &= ~0xF;
2795 + reg |= 0x1;
2796 + agnx_write32(ctl, AGNX_SPI_CFG, reg);
2797 +
2798 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1101);
2799 +
2800 + num = get_active_chains(priv);
2801 + printk(KERN_INFO PFX "Active chains are %d\n", num);
2802 +
2803 + reg = agnx_read32(ctl, AGNX_SPI_CFG);
2804 + reg &= ~0xF;
2805 + agnx_write32(ctl, AGNX_SPI_CFG, reg);
2806 +
2807 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1908);
2808 +} /* rf_chips_init */
2809 +
2810 +
2811 +static u32 channel_tbl[15][9] = {
2812 + {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2813 + {1, 0x00, 0x00, 0x624, 0x00, 0x1a4, 0x28, 0x00, 0x1e},
2814 + {2, 0x00, 0x00, 0x615, 0x00, 0x1ae, 0x28, 0x00, 0x1e},
2815 + {3, 0x00, 0x00, 0x61a, 0x00, 0x1ae, 0x28, 0x00, 0x1e},
2816 + {4, 0x00, 0x00, 0x61f, 0x00, 0x1ae, 0x28, 0x00, 0x1e},
2817 + {5, 0x00, 0x00, 0x624, 0x00, 0x1ae, 0x28, 0x00, 0x1e},
2818 + {6, 0x00, 0x00, 0x61f, 0x00, 0x1b3, 0x28, 0x00, 0x1e},
2819 + {7, 0x00, 0x00, 0x624, 0x00, 0x1b3, 0x28, 0x00, 0x1e},
2820 + {8, 0x00, 0x00, 0x629, 0x00, 0x1b3, 0x28, 0x00, 0x1e},
2821 + {9, 0x00, 0x00, 0x624, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
2822 + {10, 0x00, 0x00, 0x629, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
2823 + {11, 0x00, 0x00, 0x62e, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
2824 + {12, 0x00, 0x00, 0x633, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
2825 + {13, 0x00, 0x00, 0x628, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
2826 + {14, 0x00, 0x00, 0x644, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
2827 +};
2828 +
2829 +
2830 +static inline void
2831 +channel_tbl_write(struct agnx_priv *priv, unsigned int channel, unsigned int reg_num)
2832 +{
2833 + void __iomem *ctl = priv->ctl;
2834 + u32 reg;
2835 +
2836 + reg = channel_tbl[channel][reg_num];
2837 + reg <<= 4;
2838 + reg |= reg_num;
2839 + spi_sy_write(ctl, SYNTH_CHIP, reg);
2840 +}
2841 +
2842 +static void synth_freq_set(struct agnx_priv *priv, unsigned int channel)
2843 +{
2844 + void __iomem *ctl = priv->ctl;
2845 + u32 reg;
2846 + AGNX_TRACE;
2847 +
2848 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
2849 +
2850 + /* Set the Clock bits to 50NS */
2851 + reg = agnx_read32(ctl, AGNX_SPI_CFG);
2852 + reg &= ~0xF;
2853 + reg |= 0x1;
2854 + agnx_write32(ctl, AGNX_SPI_CFG, reg);
2855 +
2856 + /* Write 0x00c0 to LSW and 0x3 to MSW of Synth Chip */
2857 + spi_sy_write(ctl, SYNTH_CHIP, 0x300c0);
2858 +
2859 + spi_sy_write(ctl, SYNTH_CHIP, 0x32);
2860 +
2861 + /* # Write to Register 1 on the Synth Chip */
2862 + channel_tbl_write(priv, channel, 1);
2863 + /* # Write to Register 3 on the Synth Chip */
2864 + channel_tbl_write(priv, channel, 3);
2865 + /* # Write to Register 6 on the Synth Chip */
2866 + channel_tbl_write(priv, channel, 6);
2867 + /* # Write to Register 5 on the Synth Chip */
2868 + channel_tbl_write(priv, channel, 5);
2869 + /* # Write to register 8 on the Synth Chip */
2870 + channel_tbl_write(priv, channel, 8);
2871 +
2872 + /* FIXME Clear the clock bits */
2873 + reg = agnx_read32(ctl, AGNX_SPI_CFG);
2874 + reg &= ~0xf;
2875 + agnx_write32(ctl, AGNX_SPI_CFG, reg);
2876 +} /* synth_chip_init */
2877 +
2878 +
2879 +static void antenna_init(struct agnx_priv *priv, int num_antenna)
2880 +{
2881 + void __iomem *ctl = priv->ctl;
2882 +
2883 + switch (num_antenna) {
2884 + case 1:
2885 + agnx_write32(ctl, AGNX_GCR_NLISTANT, 1);
2886 + agnx_write32(ctl, AGNX_GCR_NMEASANT, 1);
2887 + agnx_write32(ctl, AGNX_GCR_NACTIANT, 1);
2888 + agnx_write32(ctl, AGNX_GCR_NCAPTANT, 1);
2889 +
2890 + agnx_write32(ctl, AGNX_GCR_ANTCFG, 7);
2891 + agnx_write32(ctl, AGNX_GCR_BOACT, 34);
2892 + agnx_write32(ctl, AGNX_GCR_BOINACT, 34);
2893 + agnx_write32(ctl, AGNX_GCR_BODYNA, 30);
2894 +
2895 + agnx_write32(ctl, AGNX_GCR_THD0A, 125);
2896 + agnx_write32(ctl, AGNX_GCR_THD0AL, 100);
2897 + agnx_write32(ctl, AGNX_GCR_THD0B, 90);
2898 +
2899 + agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 80);
2900 + agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
2901 + agnx_write32(ctl, AGNX_GCR_SIGLTH, 16);
2902 + break;
2903 + case 2:
2904 + agnx_write32(ctl, AGNX_GCR_NLISTANT, 2);
2905 + agnx_write32(ctl, AGNX_GCR_NMEASANT, 2);
2906 + agnx_write32(ctl, AGNX_GCR_NACTIANT, 2);
2907 + agnx_write32(ctl, AGNX_GCR_NCAPTANT, 2);
2908 + agnx_write32(ctl, AGNX_GCR_ANTCFG, 15);
2909 + agnx_write32(ctl, AGNX_GCR_BOACT, 36);
2910 + agnx_write32(ctl, AGNX_GCR_BOINACT, 36);
2911 + agnx_write32(ctl, AGNX_GCR_BODYNA, 32);
2912 + agnx_write32(ctl, AGNX_GCR_THD0A, 120);
2913 + agnx_write32(ctl, AGNX_GCR_THD0AL, 100);
2914 + agnx_write32(ctl, AGNX_GCR_THD0B, 80);
2915 + agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70);
2916 + agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
2917 + agnx_write32(ctl, AGNX_GCR_SIGLTH, 32);
2918 + break;
2919 + case 3:
2920 + agnx_write32(ctl, AGNX_GCR_NLISTANT, 3);
2921 + agnx_write32(ctl, AGNX_GCR_NMEASANT, 3);
2922 + agnx_write32(ctl, AGNX_GCR_NACTIANT, 3);
2923 + agnx_write32(ctl, AGNX_GCR_NCAPTANT, 3);
2924 + agnx_write32(ctl, AGNX_GCR_ANTCFG, 31);
2925 + agnx_write32(ctl, AGNX_GCR_BOACT, 36);
2926 + agnx_write32(ctl, AGNX_GCR_BOINACT, 36);
2927 + agnx_write32(ctl, AGNX_GCR_BODYNA, 32);
2928 + agnx_write32(ctl, AGNX_GCR_THD0A, 100);
2929 + agnx_write32(ctl, AGNX_GCR_THD0AL, 100);
2930 + agnx_write32(ctl, AGNX_GCR_THD0B, 70);
2931 + agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70);
2932 + agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
2933 + agnx_write32(ctl, AGNX_GCR_SIGLTH, 48);
2934 +// agnx_write32(ctl, AGNX_GCR_SIGLTH, 16);
2935 + break;
2936 + default:
2937 + printk(KERN_WARNING PFX "Unknow antenna number\n");
2938 + }
2939 +} /* antenna_init */
2940 +
2941 +static void chain_update(struct agnx_priv *priv, u32 chain)
2942 +{
2943 + void __iomem *ctl = priv->ctl;
2944 + u32 reg;
2945 + AGNX_TRACE;
2946 +
2947 + spi_rc_write(ctl, RF_CHIP0, 0x20);
2948 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
2949 +
2950 + if (reg == 0x4)
2951 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000);
2952 + else if (reg != 0x0)
2953 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
2954 + else {
2955 + if (chain == 3 || chain == 6) {
2956 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
2957 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
2958 + } else if (chain == 2 || chain == 4) {
2959 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000);
2960 + spi_rf_write(ctl, RF_CHIP2, 0x1005);
2961 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x824);
2962 + } else if (chain == 1) {
2963 + spi_rf_write(ctl, RF_CHIP0, reg|0x1000);
2964 + spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1004);
2965 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xc36);
2966 + }
2967 + }
2968 +
2969 + spi_rc_write(ctl, RF_CHIP0, 0x22);
2970 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
2971 +
2972 + switch (reg) {
2973 + case 0:
2974 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1005);
2975 + break;
2976 + case 1:
2977 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
2978 + break;
2979 + case 2:
2980 + if (chain == 6 || chain == 4) {
2981 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1202);
2982 + spi_rf_write(ctl, RF_CHIP2, 0x1005);
2983 + } else if (chain < 3) {
2984 + spi_rf_write(ctl, RF_CHIP0, 0x1202);
2985 + spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1005);
2986 + }
2987 + break;
2988 + default:
2989 + if (chain == 3) {
2990 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203);
2991 + spi_rf_write(ctl, RF_CHIP2, 0x1201);
2992 + } else if (chain == 2) {
2993 + spi_rf_write(ctl, RF_CHIP0, 0x1203);
2994 + spi_rf_write(ctl, RF_CHIP2, 0x1200);
2995 + spi_rf_write(ctl, RF_CHIP1, 0x1201);
2996 + } else if (chain == 1) {
2997 + spi_rf_write(ctl, RF_CHIP0, 0x1203);
2998 + spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1200);
2999 + } else if (chain == 4) {
3000 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203);
3001 + spi_rf_write(ctl, RF_CHIP2, 0x1201);
3002 + } else {
3003 + spi_rf_write(ctl, RF_CHIP0, 0x1203);
3004 + spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1201);
3005 + }
3006 + }
3007 +} /* chain_update */
3008 +
3009 +static void antenna_config(struct agnx_priv *priv)
3010 +{
3011 + void __iomem *ctl = priv->ctl;
3012 + u32 reg;
3013 + AGNX_TRACE;
3014 +
3015 + /* Write 0x0 to the TX Management Control Register Enable bit */
3016 + reg = agnx_read32(ctl, AGNX_TXM_CTL);
3017 + reg &= ~0x1;
3018 + agnx_write32(ctl, AGNX_TXM_CTL, reg);
3019 +
3020 + /* FIXME */
3021 + /* Set initial value based on number of Antennae */
3022 + antenna_init(priv, 3);
3023 +
3024 + /* FIXME Update Power Templates for current valid Stations */
3025 + /* sta_power_init(priv, 0);*/
3026 +
3027 + /* FIXME the number of chains should get from eeprom*/
3028 + chain_update(priv, AGNX_CHAINS_MAX);
3029 +} /* antenna_config */
3030 +
3031 +void calibrate_oscillator(struct agnx_priv *priv)
3032 +{
3033 + void __iomem *ctl = priv->ctl;
3034 + u32 reg;
3035 + AGNX_TRACE;
3036 +
3037 + spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
3038 + reg = agnx_read32(ctl, AGNX_GCR_GAINSET1);
3039 + reg |= 0x10;
3040 + agnx_write32(ctl, AGNX_GCR_GAINSET1, reg);
3041 +
3042 + agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 1);
3043 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 1);
3044 +
3045 + agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff);
3046 +
3047 + agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27);
3048 + agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
3049 + /* (Residual DC Calibration) to Calibration Mode */
3050 + agnx_write32(ctl, AGNX_ACI_MODE, 0x2);
3051 +
3052 + spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x1004);
3053 + agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff);
3054 + /* (TX LO Calibration) to Calibration Mode */
3055 + agnx_write32(ctl, AGNX_ACI_MODE, 0x4);
3056 +
3057 + do {
3058 + u32 reg1, reg2, reg3;
3059 + /* Enable Power Saving Control */
3060 + enable_power_saving(priv);
3061 + /* Save the following registers to restore */
3062 + reg1 = ioread32(ctl + 0x11000);
3063 + reg2 = ioread32(ctl + 0xec50);
3064 + reg3 = ioread32(ctl + 0xec54);
3065 + wmb();
3066 +
3067 + agnx_write32(ctl, 0x11000, 0xcfdf);
3068 + agnx_write32(ctl, 0xec50, 0x70);
3069 + /* Restore the registers */
3070 + agnx_write32(ctl, 0x11000, reg1);
3071 + agnx_write32(ctl, 0xec50, reg2);
3072 + agnx_write32(ctl, 0xec54, reg3);
3073 + /* Disable Power Saving Control */
3074 + disable_power_saving(priv);
3075 + } while (0);
3076 +
3077 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0);
3078 +} /* calibrate_oscillator */
3079 +
3080 +
3081 +static void radio_channel_set(struct agnx_priv *priv, unsigned int channel)
3082 +{
3083 + void __iomem *ctl = priv->ctl;
3084 + unsigned int freq = priv->band.channels[channel - 1].center_freq;
3085 + u32 reg;
3086 + AGNX_TRACE;
3087 +
3088 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
3089 + /* Set SPI Clock to 50 Ns */
3090 + reg = agnx_read32(ctl, AGNX_SPI_CFG);
3091 + reg &= ~0xF;
3092 + reg |= 0x1;
3093 + agnx_write32(ctl, AGNX_SPI_CFG, reg);
3094 +
3095 + /* Clear the Disable Tx interrupt bit in Interrupt Mask */
3096 +/* reg = agnx_read32(ctl, AGNX_INT_MASK); */
3097 +/* reg &= ~IRQ_TX_DISABLE; */
3098 +/* agnx_write32(ctl, AGNX_INT_MASK, reg); */
3099 +
3100 + /* Band Selection */
3101 + reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT);
3102 + reg |= 0x8;
3103 + agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg);
3104 +
3105 + /* FIXME Set the SiLabs Chip Frequency */
3106 + synth_freq_set(priv, channel);
3107 +
3108 + reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
3109 + reg |= 0x80100030;
3110 + agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
3111 + reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
3112 + reg |= 0x20009;
3113 + agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
3114 +
3115 + agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
3116 +
3117 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1100);
3118 +
3119 + /* Load the MonitorGain Table */
3120 + monitor_gain_table_init(priv);
3121 +
3122 + /* Load the TX Fir table */
3123 + tx_fir_table_init(priv);
3124 +
3125 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
3126 + reg |= 0x8;
3127 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
3128 +
3129 + spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x22);
3130 + udelay(80);
3131 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
3132 +
3133 +
3134 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xff);
3135 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
3136 +
3137 + reg = agnx_read32(ctl, 0xec50);
3138 + reg |= 0x4f;
3139 + agnx_write32(ctl, 0xec50, reg);
3140 +
3141 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
3142 + agnx_write32(ctl, 0x11008, 0x1);
3143 + agnx_write32(ctl, 0x1100c, 0x0);
3144 + agnx_write32(ctl, 0x11008, 0x0);
3145 + agnx_write32(ctl, 0xec50, 0xc);
3146 +
3147 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
3148 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
3149 + agnx_write32(ctl, 0x11010, 0x6e);
3150 + agnx_write32(ctl, 0x11014, 0x6c);
3151 +
3152 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
3153 +
3154 + /* Calibrate the Antenna */
3155 + /* antenna_calibrate(priv); */
3156 + /* Calibrate the TxLocalOscillator */
3157 + calibrate_oscillator(priv);
3158 +
3159 + reg = agnx_read32(ctl, AGNX_PM_PMCTL);
3160 + reg &= ~0x8;
3161 + agnx_write32(ctl, AGNX_PM_PMCTL, reg);
3162 + agnx_write32(ctl, AGNX_GCR_GAININIT, 0xa);
3163 + agnx_write32(ctl, AGNX_GCR_THCD, 0x0);
3164 +
3165 + agnx_write32(ctl, 0x11018, 0xb);
3166 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x0);
3167 +
3168 + /* Write Frequency to Gain Control Channel */
3169 + agnx_write32(ctl, AGNX_GCR_RXCHANEL, freq);
3170 + /* Write 0x140000/Freq to 0x9c08 */
3171 + reg = 0x140000/freq;
3172 + agnx_write32(ctl, 0x9c08, reg);
3173 +
3174 + reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
3175 + reg &= ~0x80100030;
3176 + agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
3177 +
3178 + reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
3179 + reg &= ~0x20009;
3180 + reg |= 0x1;
3181 + agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
3182 +
3183 + agnx_write32(ctl, AGNX_ACI_MODE, 0x0);
3184 +
3185 +/* FIXME According to Number of Chains: */
3186 +
3187 +/* 1. 1: */
3188 +/* 1. Write 0x1203 to RF Chip 0 */
3189 +/* 2. Write 0x1200 to RF Chips 1 +2 */
3190 +/* 2. 2: */
3191 +/* 1. Write 0x1203 to RF Chip 0 */
3192 +/* 2. Write 0x1200 to RF Chip 2 */
3193 +/* 3. Write 0x1201 to RF Chip 1 */
3194 +/* 3. 3: */
3195 +/* 1. Write 0x1203 to RF Chip 0 */
3196 +/* 2. Write 0x1201 to RF Chip 1 + 2 */
3197 +/* 4. 4: */
3198 +/* 1. Write 0x1203 to RF Chip 0 + 1 */
3199 +/* 2. Write 0x1200 to RF Chip 2 */
3200 +
3201 +/* 5. 6: */
3202 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203);
3203 + spi_rf_write(ctl, RF_CHIP2, 0x1201);
3204 +
3205 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1000);
3206 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
3207 +
3208 + /* FIXME Set the Disable Tx interrupt bit in Interrupt Mask
3209 + (Or 0x20000 to Interrupt Mask) */
3210 +/* reg = agnx_read32(ctl, AGNX_INT_MASK); */
3211 +/* reg |= IRQ_TX_DISABLE; */
3212 +/* agnx_write32(ctl, AGNX_INT_MASK, reg); */
3213 +
3214 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
3215 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
3216 +
3217 + /* Configure the Antenna */
3218 + antenna_config(priv);
3219 +
3220 + /* Write 0x0 to Discovery Mode Enable detect G, B, A packet? */
3221 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0);
3222 +
3223 + reg = agnx_read32(ctl, AGNX_RXM_REQRATE);
3224 + reg |= 0x80000000;
3225 + agnx_write32(ctl, AGNX_RXM_REQRATE, reg);
3226 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
3227 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
3228 +
3229 + /* enable radio on and the power LED */
3230 + reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT);
3231 + reg &= ~0x1;
3232 + reg |= 0x2;
3233 + agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg);
3234 +
3235 + reg = agnx_read32(ctl, AGNX_TXM_CTL);
3236 + reg |= 0x1;
3237 + agnx_write32(ctl, AGNX_TXM_CTL, reg);
3238 +} /* radio_channel_set */
3239 +
3240 +static void base_band_filter_calibrate(struct agnx_priv *priv)
3241 +{
3242 + void __iomem *ctl = priv->ctl;
3243 +
3244 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1700);
3245 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1001);
3246 + agnx_write32(ctl, AGNX_GCR_FORCECTLCLK, 0x0);
3247 + spi_rc_write(ctl, RF_CHIP0, 0x27);
3248 + spi_rc_write(ctl, RF_CHIP1, 0x27);
3249 + spi_rc_write(ctl, RF_CHIP2, 0x27);
3250 + agnx_write32(ctl, AGNX_GCR_FORCECTLCLK, 0x1);
3251 +}
3252 +
3253 +static void print_offset(struct agnx_priv *priv, u32 chain)
3254 +{
3255 + void __iomem *ctl = priv->ctl;
3256 + u32 offset;
3257 +
3258 + iowrite32((chain), ctl + AGNX_ACI_SELCHAIN);
3259 + udelay(10);
3260 + offset = (ioread32(ctl + AGNX_ACI_OFFSET));
3261 + printk(PFX "Chain is 0x%x, Offset is 0x%x\n", chain, offset);
3262 +}
3263 +
3264 +void print_offsets(struct agnx_priv *priv)
3265 +{
3266 + print_offset(priv, 0);
3267 + print_offset(priv, 4);
3268 + print_offset(priv, 1);
3269 + print_offset(priv, 5);
3270 + print_offset(priv, 2);
3271 + print_offset(priv, 6);
3272 +}
3273 +
3274 +
3275 +struct chains {
3276 + u32 cali; /* calibrate value*/
3277 +
3278 +#define NEED_CALIBRATE 0
3279 +#define SUCCESS_CALIBRATE 1
3280 + int status;
3281 +};
3282 +
3283 +static void chain_calibrate(struct agnx_priv *priv, struct chains *chains,
3284 + unsigned int num)
3285 +{
3286 + void __iomem *ctl = priv->ctl;
3287 + u32 calibra = chains[num].cali;
3288 +
3289 + if (num < 3)
3290 + calibra |= 0x1400;
3291 + else
3292 + calibra |= 0x1500;
3293 +
3294 + switch (num) {
3295 + case 0:
3296 + case 4:
3297 + spi_rf_write(ctl, RF_CHIP0, calibra);
3298 + break;
3299 + case 1:
3300 + case 5:
3301 + spi_rf_write(ctl, RF_CHIP1, calibra);
3302 + break;
3303 + case 2:
3304 + case 6:
3305 + spi_rf_write(ctl, RF_CHIP2, calibra);
3306 + break;
3307 + default:
3308 + BUG();
3309 + }
3310 +} /* chain_calibrate */
3311 +
3312 +
3313 +static void inline get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
3314 + unsigned int num)
3315 +{
3316 + void __iomem *ctl = priv->ctl;
3317 + u32 offset;
3318 +
3319 + iowrite32((num), ctl + AGNX_ACI_SELCHAIN);
3320 + /* FIXME */
3321 + udelay(10);
3322 + offset = (ioread32(ctl + AGNX_ACI_OFFSET));
3323 +
3324 + if (offset < 0xf) {
3325 + chains[num].status = SUCCESS_CALIBRATE;
3326 + return;
3327 + }
3328 +
3329 + if (num == 0 || num == 1 || num == 2) {
3330 + if ( 0 == chains[num].cali)
3331 + chains[num].cali = 0xff;
3332 + else
3333 + chains[num].cali--;
3334 + } else
3335 + chains[num].cali++;
3336 +
3337 + chains[num].status = NEED_CALIBRATE;
3338 +}
3339 +
3340 +static inline void calibra_delay(struct agnx_priv *priv)
3341 +{
3342 + void __iomem *ctl = priv->ctl;
3343 + u32 reg;
3344 + unsigned int i = 100;
3345 +
3346 + wmb();
3347 + while (i--) {
3348 + reg = (ioread32(ctl + AGNX_ACI_STATUS));
3349 + if (reg == 0x4000)
3350 + break;
3351 + udelay(10);
3352 + }
3353 + if (!i)
3354 + printk(PFX "calibration failed\n");
3355 +}
3356 +
3357 +void do_calibration(struct agnx_priv *priv)
3358 +{
3359 + void __iomem *ctl = priv->ctl;
3360 + struct chains chains[7];
3361 + unsigned int i, j;
3362 + AGNX_TRACE;
3363 +
3364 + for (i = 0; i < 7; i++) {
3365 + if (i == 3)
3366 + continue;
3367 +
3368 + chains[i].cali = 0x7f;
3369 + chains[i].status = NEED_CALIBRATE;
3370 + }
3371 +
3372 + /* FIXME 0x300 is a magic number */
3373 + for (j = 0; j < 0x300; j++) {
3374 + if (chains[0].status == SUCCESS_CALIBRATE &&
3375 + chains[1].status == SUCCESS_CALIBRATE &&
3376 + chains[2].status == SUCCESS_CALIBRATE &&
3377 + chains[4].status == SUCCESS_CALIBRATE &&
3378 + chains[5].status == SUCCESS_CALIBRATE &&
3379 + chains[6].status == SUCCESS_CALIBRATE)
3380 + break;
3381 +
3382 + /* Attention, there is no chain 3 */
3383 + for (i = 0; i < 7; i++) {
3384 + if (i == 3)
3385 + continue;
3386 + if (chains[i].status == NEED_CALIBRATE)
3387 + chain_calibrate(priv, chains, i);
3388 + }
3389 + /* Write 0x1 to Calibration Measure */
3390 + iowrite32((0x1), ctl + AGNX_ACI_MEASURE);
3391 + calibra_delay(priv);
3392 +
3393 + for (i = 0; i < 7; i++) {
3394 + if (i == 3)
3395 + continue;
3396 +
3397 + get_calibrete_value(priv, chains, i);
3398 + }
3399 + }
3400 + printk(PFX "Clibrate times is %d\n", j);
3401 + print_offsets(priv);
3402 +} /* do_calibration */
3403 +
3404 +void antenna_calibrate(struct agnx_priv *priv)
3405 +{
3406 + void __iomem *ctl = priv->ctl;
3407 + u32 reg;
3408 + AGNX_TRACE;
3409 +
3410 + agnx_write32(ctl, AGNX_GCR_NLISTANT, 0x3);
3411 + agnx_write32(ctl, AGNX_GCR_NMEASANT, 0x3);
3412 + agnx_write32(ctl, AGNX_GCR_NACTIANT, 0x3);
3413 + agnx_write32(ctl, AGNX_GCR_NCAPTANT, 0x3);
3414 +
3415 + agnx_write32(ctl, AGNX_GCR_ANTCFG, 0x1f);
3416 + agnx_write32(ctl, AGNX_GCR_BOACT, 0x24);
3417 + agnx_write32(ctl, AGNX_GCR_BOINACT, 0x24);
3418 + agnx_write32(ctl, AGNX_GCR_BODYNA, 0x20);
3419 + agnx_write32(ctl, AGNX_GCR_THD0A, 0x64);
3420 + agnx_write32(ctl, AGNX_GCR_THD0AL, 0x64);
3421 + agnx_write32(ctl, AGNX_GCR_THD0B, 0x46);
3422 + agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x3c);
3423 + agnx_write32(ctl, AGNX_GCR_SIGHTH, 0x64);
3424 + agnx_write32(ctl, AGNX_GCR_SIGLTH, 0x30);
3425 +
3426 + spi_rc_write(ctl, RF_CHIP0, 0x20);
3427 + /* Fixme */
3428 + udelay(80);
3429 + /* 1. Should read 0x0 */
3430 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
3431 + if (0x0 != reg)
3432 + printk(KERN_WARNING PFX "Unmatched rf chips result\n");
3433 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1000);
3434 +
3435 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
3436 +
3437 + spi_rc_write(ctl, RF_CHIP0, 0x22);
3438 + udelay(80);
3439 + reg = agnx_read32(ctl, AGNX_SPI_RLSW);
3440 + if (0x0 != reg)
3441 + printk(KERN_WARNING PFX "Unmatched rf chips result\n");
3442 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1005);
3443 +
3444 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
3445 + agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
3446 +
3447 + reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
3448 + reg |= 0x1c000032;
3449 + agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
3450 + reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
3451 + reg |= 0x0003f07;
3452 + agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
3453 +
3454 + reg = agnx_read32(ctl, 0xec50);
3455 + reg |= 0x40;
3456 + agnx_write32(ctl, 0xec50, reg);
3457 +
3458 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xff8);
3459 + agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
3460 +
3461 + agnx_write32(ctl, AGNX_GCR_CHAINNUM, 0x6);
3462 + agnx_write32(ctl, 0x19874, 0x0);
3463 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1700);
3464 +
3465 + /* Calibrate the BaseBandFilter */
3466 + base_band_filter_calibrate(priv);
3467 +
3468 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1002);
3469 +
3470 + agnx_write32(ctl, AGNX_GCR_GAINSET0, 0x1d);
3471 + agnx_write32(ctl, AGNX_GCR_GAINSET1, 0x1d);
3472 + agnx_write32(ctl, AGNX_GCR_GAINSET2, 0x1d);
3473 + agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x1);
3474 +
3475 + agnx_write32(ctl, AGNX_ACI_MODE, 0x1);
3476 + agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff);
3477 +
3478 + agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27);
3479 + agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
3480 +
3481 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1400);
3482 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1500);
3483 +
3484 + /* Measure Calibration */
3485 + agnx_write32(ctl, AGNX_ACI_MEASURE, 0x1);
3486 + calibra_delay(priv);
3487 +
3488 + /* do calibration */
3489 + do_calibration(priv);
3490 +
3491 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
3492 + agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21);
3493 + agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
3494 + agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
3495 +
3496 + reg = agnx_read32(ctl, AGNX_GCR_GAINSET0);
3497 + reg &= 0xf;
3498 + agnx_write32(ctl, AGNX_GCR_GAINSET0, reg);
3499 + reg = agnx_read32(ctl, AGNX_GCR_GAINSET1);
3500 + reg &= 0xf;
3501 + agnx_write32(ctl, AGNX_GCR_GAINSET1, reg);
3502 + reg = agnx_read32(ctl, AGNX_GCR_GAINSET2);
3503 + reg &= 0xf;
3504 + agnx_write32(ctl, AGNX_GCR_GAINSET2, reg);
3505 +
3506 + agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x0);
3507 + disable_receiver(priv);
3508 +} /* antenna_calibrate */
3509 +
3510 +void __antenna_calibrate(struct agnx_priv *priv)
3511 +{
3512 + void __iomem *ctl = priv->ctl;
3513 + u32 reg;
3514 +
3515 + /* Calibrate the BaseBandFilter */
3516 + /* base_band_filter_calibrate(priv); */
3517 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1002);
3518 +
3519 +
3520 + agnx_write32(ctl, AGNX_GCR_GAINSET0, 0x1d);
3521 + agnx_write32(ctl, AGNX_GCR_GAINSET1, 0x1d);
3522 + agnx_write32(ctl, AGNX_GCR_GAINSET2, 0x1d);
3523 +
3524 + agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x1);
3525 +
3526 + agnx_write32(ctl, AGNX_ACI_MODE, 0x1);
3527 + agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff);
3528 +
3529 +
3530 + agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27);
3531 + agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
3532 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1400);
3533 + spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1500);
3534 + /* Measure Calibration */
3535 + agnx_write32(ctl, AGNX_ACI_MEASURE, 0x1);
3536 + calibra_delay(priv);
3537 + do_calibration(priv);
3538 + agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
3539 +
3540 + agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21);
3541 + agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
3542 +
3543 + agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
3544 +
3545 + reg = agnx_read32(ctl, AGNX_GCR_GAINSET0);
3546 + reg &= 0xf;
3547 + agnx_write32(ctl, AGNX_GCR_GAINSET0, reg);
3548 + reg = agnx_read32(ctl, AGNX_GCR_GAINSET1);
3549 + reg &= 0xf;
3550 + agnx_write32(ctl, AGNX_GCR_GAINSET1, reg);
3551 + reg = agnx_read32(ctl, AGNX_GCR_GAINSET2);
3552 + reg &= 0xf;
3553 + agnx_write32(ctl, AGNX_GCR_GAINSET2, reg);
3554 +
3555 +
3556 + agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x0);
3557 +
3558 + /* Write 0x3 Gain Control Discovery Mode */
3559 + enable_receiver(priv);
3560 +}
3561 +
3562 +int agnx_set_channel(struct agnx_priv *priv, unsigned int channel)
3563 +{
3564 + AGNX_TRACE;
3565 +
3566 + printk(KERN_ERR PFX "Channel is %d %s\n", channel, __func__);
3567 + radio_channel_set(priv, channel);
3568 + return 0;
3569 +}
3570 --- /dev/null
3571 +++ b/drivers/staging/agnx/sta.c
3572 @@ -0,0 +1,219 @@
3573 +#include <linux/delay.h>
3574 +#include <linux/etherdevice.h>
3575 +#include "phy.h"
3576 +#include "sta.h"
3577 +#include "debug.h"
3578 +
3579 +void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
3580 +{
3581 + void __iomem *ctl = priv->ctl;
3582 +
3583 + reglo &= 0xFFFF;
3584 + reglo |= 0x30000000;
3585 + reglo |= 0x40000000; /* Set status busy */
3586 + reglo |= sta_id << 16;
3587 +
3588 + iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
3589 + iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
3590 + iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
3591 +
3592 + reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
3593 + reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
3594 + printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
3595 +}
3596 +
3597 +void hash_write(struct agnx_priv *priv, u8 *mac_addr, u8 sta_id)
3598 +{
3599 + void __iomem *ctl = priv->ctl;
3600 + u32 reghi, reglo;
3601 +
3602 + if (!is_valid_ether_addr(mac_addr))
3603 + printk(KERN_WARNING PFX "Update hash table: Invalid hwaddr!\n");
3604 +
3605 + reghi = mac_addr[0] << 24 | mac_addr[1] << 16 | mac_addr[2] << 8 | mac_addr[3];
3606 + reglo = mac_addr[4] << 8 | mac_addr[5];
3607 + reglo |= 0x10000000; /* Set hash commmand */
3608 + reglo |= 0x40000000; /* Set status busy */
3609 + reglo |= sta_id << 16;
3610 +
3611 + iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
3612 + iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
3613 + iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
3614 +
3615 + reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
3616 + if (!(reglo & 0x80000000))
3617 + printk(KERN_WARNING PFX "Update hash table failed\n");
3618 +}
3619 +
3620 +void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
3621 +{
3622 + void __iomem *ctl = priv->ctl;
3623 +
3624 + reglo &= 0xFFFF;
3625 + reglo |= 0x20000000;
3626 + reglo |= 0x40000000; /* Set status busy */
3627 + reglo |= sta_id << 16;
3628 +
3629 + iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
3630 + iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
3631 + iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
3632 + reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
3633 +
3634 + reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
3635 + printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
3636 +
3637 +}
3638 +
3639 +void hash_dump(struct agnx_priv *priv, u8 sta_id)
3640 +{
3641 + void __iomem *ctl = priv->ctl;
3642 + u32 reghi, reglo;
3643 +
3644 + reglo = 0x0; /* dump command */
3645 + reglo|= 0x40000000; /* status bit */
3646 + iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
3647 + iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA);
3648 +
3649 + udelay(80);
3650 +
3651 + reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
3652 + reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
3653 + printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo);
3654 + reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG);
3655 + printk(PFX "hash flag is : %.8x\n", reghi);
3656 + reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_MST);
3657 + reglo = ioread32(ctl + AGNX_RXM_HASH_DUMP_LST);
3658 + printk(PFX "hash dump mst lst: %.8x%.8x\n", reghi, reglo);
3659 + reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_DATA);
3660 + printk(PFX "hash dump data: %.8x\n", reghi);
3661 +}
3662 +
3663 +void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
3664 +{
3665 + void __iomem *ctl = priv->ctl;
3666 + memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
3667 + sizeof(*power));
3668 +}
3669 +
3670 +inline void
3671 +set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
3672 +{
3673 + void __iomem *ctl = priv->ctl;
3674 + /* FIXME 2. Write Template to offset + station number */
3675 + memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
3676 + power, sizeof(*power));
3677 +}
3678 +
3679 +
3680 +void get_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
3681 + unsigned int sta_idx, unsigned int wq_idx)
3682 +{
3683 + void __iomem *data = priv->data;
3684 + memcpy_fromio(tx_wq, data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx +
3685 + sizeof(*tx_wq) * wq_idx, sizeof(*tx_wq));
3686 +
3687 +}
3688 +
3689 +inline void set_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
3690 + unsigned int sta_idx, unsigned int wq_idx)
3691 +{
3692 + void __iomem *data = priv->data;
3693 + memcpy_toio(data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx +
3694 + sizeof(*tx_wq) * wq_idx, tx_wq, sizeof(*tx_wq));
3695 +}
3696 +
3697 +
3698 +void get_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx)
3699 +{
3700 + void __iomem *data = priv->data;
3701 +
3702 + memcpy_fromio(sta, data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
3703 + sizeof(*sta));
3704 +}
3705 +
3706 +inline void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx)
3707 +{
3708 + void __iomem *data = priv->data;
3709 +
3710 + memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
3711 + sta, sizeof(*sta));
3712 +}
3713 +
3714 +/* FIXME */
3715 +void sta_power_init(struct agnx_priv *priv, unsigned int sta_idx)
3716 +{
3717 + struct agnx_sta_power power;
3718 + u32 reg;
3719 + AGNX_TRACE;
3720 +
3721 + memset(&power, 0, sizeof(power));
3722 + reg = agnx_set_bits(EDCF, EDCF_SHIFT, 0x1);
3723 + power.reg = cpu_to_le32(reg);
3724 + set_sta_power(priv, &power, sta_idx);
3725 + udelay(40);
3726 +} /* add_power_template */
3727 +
3728 +
3729 +/* @num: The #number of station that is visible to the card */
3730 +static void sta_tx_workqueue_init(struct agnx_priv *priv, unsigned int sta_idx)
3731 +{
3732 + struct agnx_sta_tx_wq tx_wq;
3733 + u32 reg;
3734 + unsigned int i;
3735 +
3736 + memset(&tx_wq, 0, sizeof(tx_wq));
3737 +
3738 + reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1);
3739 + reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1);
3740 +// reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0);
3741 + tx_wq.reg2 |= cpu_to_le32(reg);
3742 +
3743 + /* Suppose all 8 traffic class are used */
3744 + for (i = 0; i < STA_TX_WQ_NUM; i++)
3745 + set_sta_tx_wq(priv, &tx_wq, sta_idx, i);
3746 +} /* sta_tx_workqueue_init */
3747 +
3748 +
3749 +static void sta_traffic_init(struct agnx_sta_traffic *traffic)
3750 +{
3751 + u32 reg;
3752 + memset(traffic, 0, sizeof(*traffic));
3753 +
3754 + reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1);
3755 + reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1);
3756 +// reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1);
3757 + traffic->reg0 = cpu_to_le32(reg);
3758 +
3759 + /* 3. setting RX Sequence Number to 4095 */
3760 + reg = agnx_set_bits(RX_SEQUENCE_NUM, RX_SEQUENCE_NUM_SHIFT, 4095);
3761 + traffic->reg1 = cpu_to_le32(reg);
3762 +}
3763 +
3764 +
3765 +/* @num: The #number of station that is visible to the card */
3766 +void sta_init(struct agnx_priv *priv, unsigned int sta_idx)
3767 +{
3768 + /* FIXME the length of sta is 256 bytes Is that
3769 + * dangerous to stack overflow? */
3770 + struct agnx_sta sta;
3771 + u32 reg;
3772 + int i;
3773 +
3774 + memset(&sta, 0, sizeof(sta));
3775 + /* Set valid to 1 */
3776 + reg = agnx_set_bits(STATION_VALID, STATION_VALID_SHIFT, 1);
3777 + /* Set Enable Concatenation to 0 (?) */
3778 + reg |= agnx_set_bits(ENABLE_CONCATENATION, ENABLE_CONCATENATION_SHIFT, 0);
3779 + /* Set Enable Decompression to 0 (?) */
3780 + reg |= agnx_set_bits(ENABLE_DECOMPRESSION, ENABLE_DECOMPRESSION_SHIFT, 0);
3781 + sta.reg = cpu_to_le32(reg);
3782 +
3783 + /* Initialize each of the Traffic Class Structures by: */
3784 + for (i = 0; i < 8; i++)
3785 + sta_traffic_init(sta.traffic + i);
3786 +
3787 + set_sta(priv, &sta, sta_idx);
3788 + sta_tx_workqueue_init(priv, sta_idx);
3789 +} /* sta_descriptor_init */
3790 +
3791 +
3792 --- /dev/null
3793 +++ b/drivers/staging/agnx/sta.h
3794 @@ -0,0 +1,222 @@
3795 +#ifndef AGNX_STA_H_
3796 +#define AGNX_STA_H_
3797 +
3798 +#define STA_TX_WQ_NUM 8 /* The number of TX workqueue one STA has */
3799 +
3800 +struct agnx_hash_cmd {
3801 + __be32 cmdhi;
3802 +#define MACLO 0xFFFF0000
3803 +#define MACLO_SHIFT 16
3804 +#define STA_ID 0x0000FFF0
3805 +#define STA_ID_SHIFT 4
3806 +#define CMD 0x0000000C
3807 +#define CMD_SHIFT 2
3808 +#define STATUS 0x00000002
3809 +#define STATUS_SHIFT 1
3810 +#define PASS 0x00000001
3811 +#define PASS_SHIFT 1
3812 + __be32 cmdlo;
3813 +}__attribute__((__packed__));
3814 +
3815 +
3816 +/*
3817 + * Station Power Template
3818 + * FIXME Just for agn100 yet
3819 + */
3820 +struct agnx_sta_power {
3821 + __le32 reg;
3822 +#define SIGNAL 0x000000FF /* signal */
3823 +#define SIGNAL_SHIFT 0
3824 +#define RATE 0x00000F00
3825 +#define RATE_SHIFT 8
3826 +#define TIFS 0x00001000
3827 +#define TIFS_SHIFT 12
3828 +#define EDCF 0x00002000
3829 +#define EDCF_SHIFT 13
3830 +#define CHANNEL_BOND 0x00004000
3831 +#define CHANNEL_BOND_SHIFT 14
3832 +#define PHY_MODE 0x00038000
3833 +#define PHY_MODE_SHIFT 15
3834 +#define POWER_LEVEL 0x007C0000
3835 +#define POWER_LEVEL_SHIFT 18
3836 +#define NUM_TRANSMITTERS 0x00800000
3837 +#define NUM_TRANSMITTERS_SHIFT 23
3838 +} __attribute__((__packed__));
3839 +
3840 +/*
3841 + * TX Workqueue Descriptor
3842 + */
3843 +struct agnx_sta_tx_wq {
3844 + __le32 reg0;
3845 +#define HEAD_POINTER_LOW 0xFF000000 /* Head pointer low */
3846 +#define HEAD_POINTER_LOW_SHIFT 24
3847 +#define TAIL_POINTER 0x00FFFFFF /* Tail pointer */
3848 +#define TAIL_POINTER_SHIFT 0
3849 +
3850 + __le32 reg3;
3851 +#define ACK_POINTER_LOW 0xFFFF0000 /* ACK pointer low */
3852 +#define ACK_POINTER_LOW_SHIFT 16
3853 +#define HEAD_POINTER_HIGH 0x0000FFFF /* Head pointer high */
3854 +#define HEAD_POINTER_HIGH_SHIFT 0
3855 +
3856 + __le32 reg1;
3857 +/* ACK timeout tail packet count */
3858 +#define ACK_TIMOUT_TAIL_PACK_CNT 0xFFF00000
3859 +#define ACK_TIMOUT_TAIL_PACK_CNT_SHIFT 20
3860 +/* Head timeout tail packet count */
3861 +#define HEAD_TIMOUT_TAIL_PACK_CNT 0x000FFF00
3862 +#define HEAD_TIMOUT_TAIL_PACK_CNT_SHIFT 8
3863 +#define ACK_POINTER_HIGH 0x000000FF /* ACK pointer high */
3864 +#define ACK_POINTER_HIGH_SHIFT 0
3865 +
3866 + __le32 reg2;
3867 +#define WORK_QUEUE_VALID 0x80000000 /* valid */
3868 +#define WORK_QUEUE_VALID_SHIFT 31
3869 +#define WORK_QUEUE_ACK_TYPE 0x40000000 /* ACK type */
3870 +#define WORK_QUEUE_ACK_TYPE_SHIFT 30
3871 +/* Head timeout window limit fragmentation count */
3872 +#define HEAD_TIMOUT_WIN_LIM_FRAG_CNT 0x3FFF0000
3873 +#define HEAD_TIMOUT_WIN_LIM_FRAG_CNT_SHIFT 16
3874 +/* Head timeout window limit byte count */
3875 +#define HEAD_TIMOUT_WIN_LIM_BYTE_CNT 0x0000FFFF
3876 +#define HEAD_TIMOUT_WIN_LIM_BYTE_CNT_SHIFT 0
3877 +} __attribute__((__packed__));
3878 +
3879 +
3880 +/*
3881 + * Traffic Class Structure
3882 + */
3883 +struct agnx_sta_traffic {
3884 + __le32 reg0;
3885 +#define ACK_TIMOUT_CNT 0xFF800000 /* ACK Timeout Counts */
3886 +#define ACK_TIMOUT_CNT_SHIFT 23
3887 +#define TRAFFIC_ACK_TYPE 0x00600000 /* ACK Type */
3888 +#define TRAFFIC_ACK_TYPE_SHIFT 21
3889 +#define NEW_PACKET 0x00100000 /* New Packet */
3890 +#define NEW_PACKET_SHIFT 20
3891 +#define TRAFFIC_VALID 0x00080000 /* Valid */
3892 +#define TRAFFIC_VALID_SHIFT 19
3893 +#define RX_HDR_DESC_POINTER 0x0007FFFF /* RX Header Descripter pointer */
3894 +#define RX_HDR_DESC_POINTER_SHIFT 0
3895 +
3896 + __le32 reg1;
3897 +#define RX_PACKET_TIMESTAMP 0xFFFF0000 /* RX Packet Timestamp */
3898 +#define RX_PACKET_TIMESTAMP_SHIFT 16
3899 +#define TRAFFIC_RESERVED 0x0000E000 /* Reserved */
3900 +#define TRAFFIC_RESERVED_SHIFT 13
3901 +#define SV 0x00001000 /* sv */
3902 +#define SV_SHIFT 12
3903 +#define RX_SEQUENCE_NUM 0x00000FFF /* RX Sequence Number */
3904 +#define RX_SEQUENCE_NUM_SHIFT 0
3905 +
3906 + __le32 tx_replay_cnt_low; /* TX Replay Counter Low */
3907 +
3908 + __le16 tx_replay_cnt_high; /* TX Replay Counter High */
3909 + __le16 rx_replay_cnt_high; /* RX Replay Counter High */
3910 +
3911 + __be32 rx_replay_cnt_low; /* RX Replay Counter Low */
3912 +} __attribute__((__packed__));
3913 +
3914 +/*
3915 + * Station Descriptors
3916 + */
3917 +struct agnx_sta {
3918 + __le32 tx_session_keys[4]; /* Transmit Session Key (0-3) */
3919 + __le32 rx_session_keys[4]; /* Receive Session Key (0-3) */
3920 +
3921 + __le32 reg;
3922 +#define ID_1 0xC0000000 /* id 1 */
3923 +#define ID_1_SHIFT 30
3924 +#define ID_0 0x30000000 /* id 0 */
3925 +#define ID_0_SHIFT 28
3926 +#define ENABLE_CONCATENATION 0x0FF00000 /* Enable concatenation */
3927 +#define ENABLE_CONCATENATION_SHIFT 20
3928 +#define ENABLE_DECOMPRESSION 0x000FF000 /* Enable decompression */
3929 +#define ENABLE_DECOMPRESSION_SHIFT 12
3930 +#define STA_RESERVED 0x00000C00 /* Reserved */
3931 +#define STA_RESERVED_SHIFT 10
3932 +#define EAP 0x00000200 /* EAP */
3933 +#define EAP_SHIFT 9
3934 +#define ED_NULL 0x00000100 /* ED NULL */
3935 +#define ED_NULL_SHIFT 8
3936 +#define ENCRYPTION_POLICY 0x000000E0 /* Encryption Policy */
3937 +#define ENCRYPTION_POLICY_SHIFT 5
3938 +#define DEFINED_KEY_ID 0x00000018 /* Defined Key ID */
3939 +#define DEFINED_KEY_ID_SHIFT 3
3940 +#define FIXED_KEY 0x00000004 /* Fixed Key */
3941 +#define FIXED_KEY_SHIFT 2
3942 +#define KEY_VALID 0x00000002 /* Key Valid */
3943 +#define KEY_VALID_SHIFT 1
3944 +#define STATION_VALID 0x00000001 /* Station Valid */
3945 +#define STATION_VALID_SHIFT 0
3946 +
3947 + __le32 tx_aes_blks_unicast; /* TX AES Blks Unicast */
3948 + __le32 rx_aes_blks_unicast; /* RX AES Blks Unicast */
3949 +
3950 + __le16 aes_format_err_unicast_cnt; /* AES Format Error Unicast Counts */
3951 + __le16 aes_replay_unicast; /* AES Replay Unicast */
3952 +
3953 + __le16 aes_decrypt_err_unicast; /* AES Decrypt Error Unicast */
3954 + __le16 aes_decrypt_err_default; /* AES Decrypt Error default */
3955 +
3956 + __le16 single_retry_packets; /* Single Retry Packets */
3957 + __le16 failed_tx_packets; /* Failed Tx Packets */
3958 +
3959 + __le16 muti_retry_packets; /* Multiple Retry Packets */
3960 + __le16 ack_timeouts; /* ACK Timeouts */
3961 +
3962 + __le16 frag_tx_cnt; /* Fragment TX Counts */
3963 + __le16 rts_brq_sent; /* RTS Brq Sent */
3964 +
3965 + __le16 tx_packets; /* TX Packets */
3966 + __le16 cts_back_timeout; /* CTS Back Timeout */
3967 +
3968 + __le32 phy_stats_high; /* PHY Stats High */
3969 + __le32 phy_stats_low; /* PHY Stats Low */
3970 +
3971 + struct agnx_sta_traffic traffic[8]; /* Traffic Class Structure (8) */
3972 +
3973 + __le16 traffic_class0_frag_success; /* Traffic Class 0 Fragment Success */
3974 + __le16 traffic_class1_frag_success; /* Traffic Class 1 Fragment Success */
3975 + __le16 traffic_class2_frag_success; /* Traffic Class 2 Fragment Success */
3976 + __le16 traffic_class3_frag_success; /* Traffic Class 3 Fragment Success */
3977 + __le16 traffic_class4_frag_success; /* Traffic Class 4 Fragment Success */
3978 + __le16 traffic_class5_frag_success; /* Traffic Class 5 Fragment Success */
3979 + __le16 traffic_class6_frag_success; /* Traffic Class 6 Fragment Success */
3980 + __le16 traffic_class7_frag_success; /* Traffic Class 7 Fragment Success */
3981 +
3982 + __le16 num_frag_non_prime_rates; /* number of Fragments for non-prime rates */
3983 + __le16 ack_timeout_non_prime_rates; /* ACK Timeout for non-prime rates */
3984 +
3985 +} __attribute__((__packed__));
3986 +
3987 +
3988 +struct agnx_beacon_hdr {
3989 + struct agnx_sta_power power; /* Tx Station Power Template */
3990 + u8 phy_hdr[6]; /* PHY Hdr */
3991 + u8 frame_len_lo; /* Frame Length Lo */
3992 + u8 frame_len_hi; /* Frame Length Hi */
3993 + u8 mac_hdr[24]; /* MAC Header */
3994 + /* FIXME */
3995 + /* 802.11(abg) beacon */
3996 +} __attribute__((__packed__));
3997 +
3998 +void hash_write(struct agnx_priv *priv, u8 *mac_addr, u8 sta_id);
3999 +void hash_dump(struct agnx_priv *priv, u8 sta_id);
4000 +void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id);
4001 +void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id);
4002 +
4003 +void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx);
4004 +void set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power,
4005 + unsigned int sta_idx);
4006 +void get_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
4007 + unsigned int sta_idx, unsigned int wq_idx);
4008 +void set_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
4009 + unsigned int sta_idx, unsigned int wq_idx);
4010 +void get_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx);
4011 +void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx);
4012 +
4013 +void sta_power_init(struct agnx_priv *priv, unsigned int num);
4014 +void sta_init(struct agnx_priv *priv, unsigned int num);
4015 +
4016 +#endif /* AGNX_STA_H_ */
4017 --- /dev/null
4018 +++ b/drivers/staging/agnx/table.c
4019 @@ -0,0 +1,168 @@
4020 +#include <linux/pci.h>
4021 +#include <linux/delay.h>
4022 +#include "agnx.h"
4023 +#include "debug.h"
4024 +#include "phy.h"
4025 +
4026 +static const u32
4027 +tx_fir_table[] = { 0x19, 0x5d, 0xce, 0x151, 0x1c3, 0x1ff, 0x1ea, 0x17c, 0xcf,
4028 + 0x19, 0x38e, 0x350, 0x362, 0x3ad, 0x5, 0x44, 0x59, 0x49,
4029 + 0x21, 0x3f7, 0x3e0, 0x3e3, 0x3f3, 0x0 };
4030 +
4031 +void tx_fir_table_init(struct agnx_priv *priv)
4032 +{
4033 + void __iomem *ctl = priv->ctl;
4034 + int i;
4035 +
4036 + for (i = 0; i < ARRAY_SIZE(tx_fir_table); i++)
4037 + iowrite32(tx_fir_table[i], ctl + AGNX_FIR_BASE + i*4);
4038 +} /* fir_table_setup */
4039 +
4040 +
4041 +static const u32
4042 +gain_table[] = { 0x8, 0x8, 0xf, 0x13, 0x17, 0x1b, 0x1f, 0x23, 0x27, 0x2b,
4043 + 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, 0x47, 0x4b, 0x4f,
4044 + 0x53, 0x57, 0x5b, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
4045 + 0x5f, 0x5f, 0x5f, 0x5f };
4046 +
4047 +void gain_table_init(struct agnx_priv *priv)
4048 +{
4049 + void __iomem *ctl = priv->ctl;
4050 + int i;
4051 +
4052 + for (i = 0; i < ARRAY_SIZE(gain_table); i++) {
4053 + iowrite32(gain_table[i], ctl + AGNX_GAIN_TABLE + i*4);
4054 + iowrite32(gain_table[i], ctl + AGNX_GAIN_TABLE + i*4 + 0x80);
4055 + }
4056 +} /* gain_table_init */
4057 +
4058 +void monitor_gain_table_init(struct agnx_priv *priv)
4059 +{
4060 + void __iomem *ctl = priv->ctl;
4061 + unsigned int i;
4062 +
4063 + for (i = 0; i < 0x44; i += 4) {
4064 + iowrite32(0x61, ctl + AGNX_MONGCR_BASE + i);
4065 + iowrite32(0x61, ctl + AGNX_MONGCR_BASE + 0x200 + i);
4066 + }
4067 + for (i = 0x44; i < 0x64; i += 4) {
4068 + iowrite32(0x6e, ctl + AGNX_MONGCR_BASE + i);
4069 + iowrite32(0x6e, ctl + AGNX_MONGCR_BASE + 0x200 + i);
4070 + }
4071 + for (i = 0x64; i < 0x94; i += 4) {
4072 + iowrite32(0x7a, ctl + AGNX_MONGCR_BASE + i);
4073 + iowrite32(0x7a, ctl + AGNX_MONGCR_BASE + 0x200 + i);
4074 + }
4075 + for (i = 0x94; i < 0xdc; i += 4) {
4076 + iowrite32(0x87, ctl + AGNX_MONGCR_BASE + i);
4077 + iowrite32(0x87, ctl + AGNX_MONGCR_BASE + 0x200 + i);
4078 + }
4079 + for (i = 0xdc; i < 0x148; i += 4) {
4080 + iowrite32(0x95, ctl + AGNX_MONGCR_BASE + i);
4081 + iowrite32(0x95, ctl + AGNX_MONGCR_BASE + 0x200 + i);
4082 + }
4083 + for (i = 0x148; i < 0x1e8; i += 4) {
4084 + iowrite32(0xa2, ctl + AGNX_MONGCR_BASE + i);
4085 + iowrite32(0xa2, ctl + AGNX_MONGCR_BASE + 0x200 + i);
4086 + }
4087 + for (i = 0x1e8; i <= 0x1fc; i += 4) {
4088 + iowrite32(0xb0, ctl + AGNX_MONGCR_BASE + i);
4089 + iowrite32(0xb0, ctl + AGNX_MONGCR_BASE + 0x200 + i);
4090 + }
4091 +} /* monitor_gain_table_init */
4092 +
4093 +
4094 +void routing_table_init(struct agnx_priv *priv)
4095 +{
4096 + void __iomem *ctl = priv->ctl;
4097 + unsigned int type, subtype;
4098 + u32 reg;
4099 +
4100 + disable_receiver(priv);
4101 +
4102 + for ( type = 0; type < 0x3; type++ ) {
4103 + for (subtype = 0; subtype < 0x10; subtype++) {
4104 + /* 1. Set Routing table to R/W and to Return status on Read */
4105 + reg = (type << ROUTAB_TYPE_SHIFT) |
4106 + (subtype << ROUTAB_SUBTYPE_SHIFT);
4107 + reg |= (1 << ROUTAB_RW_SHIFT) | (1 << ROUTAB_STATUS_SHIFT);
4108 + if (type == ROUTAB_TYPE_DATA) {
4109 + /* NULL goes to RFP */
4110 + if (subtype == ROUTAB_SUBTYPE_NULL)
4111 +// reg |= ROUTAB_ROUTE_RFP;
4112 + reg |= ROUTAB_ROUTE_CPU;
4113 + /* QOS NULL goes to CPU */
4114 + else if (subtype == ROUTAB_SUBTYPE_QOSNULL)
4115 + reg |= ROUTAB_ROUTE_CPU;
4116 + /* All Data and QOS data subtypes go to Encryption */
4117 + else if ((subtype == ROUTAB_SUBTYPE_DATA) ||
4118 + (subtype == ROUTAB_SUBTYPE_DATAACK) ||
4119 + (subtype == ROUTAB_SUBTYPE_DATAPOLL) ||
4120 + (subtype == ROUTAB_SUBTYPE_DATAPOLLACK) ||
4121 + (subtype == ROUTAB_SUBTYPE_QOSDATA) ||
4122 + (subtype == ROUTAB_SUBTYPE_QOSDATAACK) ||
4123 + (subtype == ROUTAB_SUBTYPE_QOSDATAPOLL) ||
4124 + (subtype == ROUTAB_SUBTYPE_QOSDATAACKPOLL))
4125 + reg |= ROUTAB_ROUTE_ENCRY;
4126 +// reg |= ROUTAB_ROUTE_CPU;
4127 + /*Drop NULL and QOS NULL ack, poll and poll ack*/
4128 + else if ((subtype == ROUTAB_SUBTYPE_NULLACK) ||
4129 + (subtype == ROUTAB_SUBTYPE_QOSNULLACK) ||
4130 + (subtype == ROUTAB_SUBTYPE_NULLPOLL) ||
4131 + (subtype == ROUTAB_SUBTYPE_QOSNULLPOLL) ||
4132 + (subtype == ROUTAB_SUBTYPE_NULLPOLLACK) ||
4133 + (subtype == ROUTAB_SUBTYPE_QOSNULLPOLLACK))
4134 +// reg |= ROUTAB_ROUTE_DROP;
4135 + reg |= ROUTAB_ROUTE_CPU;
4136 + }
4137 + else
4138 + reg |= (ROUTAB_ROUTE_CPU);
4139 + iowrite32(reg, ctl + AGNX_RXM_ROUTAB);
4140 + /* Check to verify that the status bit cleared */
4141 + routing_table_delay();
4142 + }
4143 + }
4144 + enable_receiver(priv);
4145 +} /* routing_table_init */
4146 +
4147 +void tx_engine_lookup_tbl_init(struct agnx_priv *priv)
4148 +{
4149 + void __iomem *data = priv->data;
4150 + unsigned int i;
4151 +
4152 + for (i = 0; i <= 28; i += 4)
4153 + iowrite32(0xb00c, data + AGNX_ENGINE_LOOKUP_TBL + i);
4154 + for (i = 32; i <= 120; i += 8) {
4155 + iowrite32(0x1e58, data + AGNX_ENGINE_LOOKUP_TBL + i);
4156 + iowrite32(0xb00c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
4157 + }
4158 +
4159 + for (i = 128; i <= 156; i += 4)
4160 + iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i);
4161 + for (i = 160; i <= 248; i += 8) {
4162 + iowrite32(0x1858, data + AGNX_ENGINE_LOOKUP_TBL + i);
4163 + iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
4164 + }
4165 +
4166 + for (i = 256; i <= 284; i += 4)
4167 + iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i);
4168 + for (i = 288; i <= 376; i += 8) {
4169 + iowrite32(0x1a58, data + AGNX_ENGINE_LOOKUP_TBL + i);
4170 + iowrite32(0x1858, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
4171 + }
4172 +
4173 + for (i = 512; i <= 540; i += 4)
4174 + iowrite32(0xc00c, data + AGNX_ENGINE_LOOKUP_TBL + i);
4175 + for (i = 544; i <= 632; i += 8) {
4176 + iowrite32(0x2058, data + AGNX_ENGINE_LOOKUP_TBL + i);
4177 + iowrite32(0xc00c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
4178 + }
4179 +
4180 + for (i = 640; i <= 668; i += 4)
4181 + iowrite32(0xc80c, data + AGNX_ENGINE_LOOKUP_TBL + i);
4182 + for (i = 672; i <= 764; i += 8) {
4183 + iowrite32(0x2258, data + AGNX_ENGINE_LOOKUP_TBL + i);
4184 + iowrite32(0xc80c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
4185 + }
4186 +}
4187 +
4188 --- /dev/null
4189 +++ b/drivers/staging/agnx/table.h
4190 @@ -0,0 +1,10 @@
4191 +#ifndef AGNX_TABLE_H_
4192 +#define AGNX_TABLE_H_
4193 +
4194 +void tx_fir_table_init(struct agnx_priv *priv);
4195 +void gain_table_init(struct agnx_priv *priv);
4196 +void monitor_gain_table_init(struct agnx_priv *priv);
4197 +void routing_table_init(struct agnx_priv *priv);
4198 +void tx_engine_lookup_tbl_init(struct agnx_priv *priv);
4199 +
4200 +#endif /* AGNX_TABLE_H_ */
4201 --- /dev/null
4202 +++ b/drivers/staging/agnx/TODO
4203 @@ -0,0 +1,22 @@
4204 +2008 7/18
4205 +
4206 +The RX has can't receive OFDM packet correctly,
4207 +Guess it need be do RX calibrate.
4208 +
4209 +
4210 +before 2008 3/1
4211 +
4212 +1: The RX get too much "CRC failed" pakets, it make the card work very unstable,
4213 +2: After running a while, the card will get infinity "RX Frame" and "Error"
4214 +interrupt, not know the root reason so far, try to fix it
4215 +3: Using two tx queue txd and txm but not only txm.
4216 +4: Set the hdr correctly.
4217 +5: Try to do recalibrate correvtly
4218 +6: To support G mode in future
4219 +7: Fix the mac address can't be readed and set correctly in BE machine.
4220 +8: Fix include and exclude FCS in promisous mode and manage mode
4221 +9: Using sta_notify to notice sta change
4222 +10: Turn on frame reception at the end of start
4223 +11: Guess the card support HW_MULTICAST_FILTER
4224 +12: The tx process should be implment atomic?
4225 +13: Using mac80211 function to control the TX&RX LED.
4226 --- /dev/null
4227 +++ b/drivers/staging/agnx/xmit.c
4228 @@ -0,0 +1,819 @@
4229 +/**
4230 + * Airgo MIMO wireless driver
4231 + *
4232 + * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
4233 +
4234 + * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
4235 + * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
4236 +
4237 + * This program is free software; you can redistribute it and/or modify
4238 + * it under the terms of the GNU General Public License version 2 as
4239 + * published by the Free Software Foundation.
4240 + */
4241 +
4242 +#include <linux/pci.h>
4243 +#include <linux/delay.h>
4244 +#include "agnx.h"
4245 +#include "debug.h"
4246 +#include "phy.h"
4247 +
4248 +unsigned int rx_frame_cnt = 0;
4249 +//unsigned int local_tx_sent_cnt = 0;
4250 +
4251 +static inline void disable_rx_engine(struct agnx_priv *priv)
4252 +{
4253 + void __iomem *ctl = priv->ctl;
4254 + iowrite32(0x100, ctl + AGNX_CIR_RXCTL);
4255 + /* Wait for RX Control to have the Disable Rx Interrupt (0x100) set */
4256 + ioread32(ctl + AGNX_CIR_RXCTL);
4257 +}
4258 +
4259 +static inline void enable_rx_engine(struct agnx_priv *priv)
4260 +{
4261 + void __iomem *ctl = priv->ctl;
4262 + iowrite32(0x80, ctl + AGNX_CIR_RXCTL);
4263 + ioread32(ctl + AGNX_CIR_RXCTL);
4264 +}
4265 +
4266 +inline void disable_rx_interrupt(struct agnx_priv *priv)
4267 +{
4268 + void __iomem *ctl = priv->ctl;
4269 + u32 reg;
4270 +
4271 + disable_rx_engine(priv);
4272 + reg = ioread32(ctl + AGNX_CIR_RXCFG);
4273 + reg &= ~0x20;
4274 + iowrite32(reg, ctl + AGNX_CIR_RXCFG);
4275 + ioread32(ctl + AGNX_CIR_RXCFG);
4276 +}
4277 +
4278 +inline void enable_rx_interrupt(struct agnx_priv *priv)
4279 +{
4280 + void __iomem *ctl = priv->ctl;
4281 + u32 reg;
4282 +
4283 + reg = ioread32(ctl + AGNX_CIR_RXCFG);
4284 + reg |= 0x20;
4285 + iowrite32(reg, ctl + AGNX_CIR_RXCFG);
4286 + ioread32(ctl + AGNX_CIR_RXCFG);
4287 + enable_rx_engine(priv);
4288 +}
4289 +
4290 +static inline void rx_desc_init(struct agnx_priv *priv, unsigned int idx)
4291 +{
4292 + struct agnx_desc *desc = priv->rx.desc + idx;
4293 + struct agnx_info *info = priv->rx.info + idx;
4294 +
4295 + memset(info, 0, sizeof(*info));
4296 +
4297 + info->dma_len = IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct agnx_hdr);
4298 + info->skb = dev_alloc_skb(info->dma_len);
4299 + if (info->skb == NULL)
4300 + agnx_bug("refill err");
4301 +
4302 + info->mapping = pci_map_single(priv->pdev, skb_tail_pointer(info->skb),
4303 + info->dma_len, PCI_DMA_FROMDEVICE);
4304 + memset(desc, 0, sizeof(*desc));
4305 + desc->dma_addr = cpu_to_be32(info->mapping);
4306 + /* Set the owner to the card */
4307 + desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER);
4308 +}
4309 +
4310 +static inline void rx_desc_reinit(struct agnx_priv *priv, unsigned int idx)
4311 +{
4312 + struct agnx_info *info = priv->rx.info + idx;
4313 +
4314 + /* Cause ieee80211 will free the skb buffer, so we needn't to free it again?! */
4315 + pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE);
4316 + rx_desc_init(priv, idx);
4317 +}
4318 +
4319 +static inline void rx_desc_reusing(struct agnx_priv *priv, unsigned int idx)
4320 +{
4321 + struct agnx_desc *desc = priv->rx.desc + idx;
4322 + struct agnx_info *info = priv->rx.info + idx;
4323 +
4324 + memset(desc, 0, sizeof(*desc));
4325 + desc->dma_addr = cpu_to_be32(info->mapping);
4326 + /* Set the owner to the card */
4327 + desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER);
4328 +}
4329 +
4330 +static void rx_desc_free(struct agnx_priv *priv, unsigned int idx)
4331 +{
4332 + struct agnx_desc *desc = priv->rx.desc + idx;
4333 + struct agnx_info *info = priv->rx.info + idx;
4334 +
4335 + BUG_ON(!desc || !info);
4336 + if (info->mapping)
4337 + pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE);
4338 + if (info->skb)
4339 + dev_kfree_skb(info->skb);
4340 + memset(info, 0, sizeof(*info));
4341 + memset(desc, 0, sizeof(*desc));
4342 +}
4343 +
4344 +static inline void __tx_desc_free(struct agnx_priv *priv,
4345 + struct agnx_desc *desc, struct agnx_info *info)
4346 +{
4347 + BUG_ON(!desc || !info);
4348 + /* TODO make sure mapping, skb and len are consistency */
4349 + if (info->mapping)
4350 + pci_unmap_single(priv->pdev, info->mapping,
4351 + info->dma_len, PCI_DMA_TODEVICE);
4352 + if (info->type == PACKET)
4353 + dev_kfree_skb(info->skb);
4354 +
4355 + memset(info, 0, sizeof(*info));
4356 + memset(desc, 0, sizeof(*desc));
4357 +}
4358 +
4359 +static void txm_desc_free(struct agnx_priv *priv, unsigned int idx)
4360 +{
4361 + struct agnx_desc *desc = priv->txm.desc + idx;
4362 + struct agnx_info *info = priv->txm.info + idx;
4363 +
4364 + __tx_desc_free(priv, desc, info);
4365 +}
4366 +
4367 +static void txd_desc_free(struct agnx_priv *priv, unsigned int idx)
4368 +{
4369 + struct agnx_desc *desc = priv->txd.desc + idx;
4370 + struct agnx_info *info = priv->txd.info + idx;
4371 +
4372 + __tx_desc_free(priv, desc, info);
4373 +}
4374 +
4375 +int fill_rings(struct agnx_priv *priv)
4376 +{
4377 + void __iomem *ctl = priv->ctl;
4378 + unsigned int i;
4379 + u32 reg;
4380 + AGNX_TRACE;
4381 +
4382 + priv->txd.idx_sent = priv->txm.idx_sent = 0;
4383 + priv->rx.idx = priv->txm.idx = priv->txd.idx = 0;
4384 +
4385 + for (i = 0; i < priv->rx.size; i++)
4386 + rx_desc_init(priv, i);
4387 + for (i = 0; i < priv->txm.size; i++) {
4388 + memset(priv->txm.desc + i, 0, sizeof(struct agnx_desc));
4389 + memset(priv->txm.info + i, 0, sizeof(struct agnx_info));
4390 + }
4391 + for (i = 0; i < priv->txd.size; i++) {
4392 + memset(priv->txd.desc + i, 0, sizeof(struct agnx_desc));
4393 + memset(priv->txd.info + i, 0, sizeof(struct agnx_info));
4394 + }
4395 +
4396 + /* FIXME Set the card RX TXM and TXD address */
4397 + agnx_write32(ctl, AGNX_CIR_RXCMSTART, priv->rx.dma);
4398 + agnx_write32(ctl, AGNX_CIR_RXCMEND, priv->txm.dma);
4399 +
4400 + agnx_write32(ctl, AGNX_CIR_TXMSTART, priv->txm.dma);
4401 + agnx_write32(ctl, AGNX_CIR_TXMEND, priv->txd.dma);
4402 +
4403 + agnx_write32(ctl, AGNX_CIR_TXDSTART, priv->txd.dma);
4404 + agnx_write32(ctl, AGNX_CIR_TXDEND, priv->txd.dma +
4405 + sizeof(struct agnx_desc) * priv->txd.size);
4406 +
4407 + /* FIXME Relinquish control of rings to card */
4408 + reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
4409 + reg &= ~0x800;
4410 + agnx_write32(ctl, AGNX_CIR_BLKCTL, reg);
4411 + return 0;
4412 +} /* fill_rings */
4413 +
4414 +void unfill_rings(struct agnx_priv *priv)
4415 +{
4416 + unsigned long flags;
4417 + unsigned int i;
4418 + AGNX_TRACE;
4419 +
4420 + spin_lock_irqsave(&priv->lock, flags);
4421 +
4422 + for (i = 0; i < priv->rx.size; i++)
4423 + rx_desc_free(priv, i);
4424 + for (i = 0; i < priv->txm.size; i++)
4425 + txm_desc_free(priv, i);
4426 + for (i = 0; i < priv->txd.size; i++)
4427 + txd_desc_free(priv, i);
4428 +
4429 + spin_unlock_irqrestore(&priv->lock, flags);
4430 +}
4431 +
4432 +/* Extract the bitrate out of a CCK PLCP header.
4433 + copy from bcm43xx driver */
4434 +static inline u8 agnx_plcp_get_bitrate_cck(__be32 *phyhdr_11b)
4435 +{
4436 + /* FIXME */
4437 + switch (*(u8 *)phyhdr_11b) {
4438 + case 0x0A:
4439 + return 0;
4440 + case 0x14:
4441 + return 1;
4442 + case 0x37:
4443 + return 2;
4444 + case 0x6E:
4445 + return 3;
4446 + }
4447 + agnx_bug("Wrong plcp rate");
4448 + return 0;
4449 +}
4450 +
4451 +/* FIXME */
4452 +static inline u8 agnx_plcp_get_bitrate_ofdm(__be32 *phyhdr_11g)
4453 +{
4454 + u8 rate = *(u8 *)phyhdr_11g & 0xF;
4455 +
4456 + printk(PFX "G mode rate is 0x%x\n", rate);
4457 + return rate;
4458 +}
4459 +
4460 +/* FIXME */
4461 +static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
4462 + struct ieee80211_rx_status *stat)
4463 +{
4464 + void __iomem *ctl = priv->ctl;
4465 + u8 *rssi;
4466 + u32 noise;
4467 + /* FIXME just for test */
4468 + int snr = 40; /* signal-to-noise ratio */
4469 +
4470 + memset(stat, 0, sizeof(*stat));
4471 + /* RSSI */
4472 + rssi = (u8 *)&hdr->phy_stats_lo;
4473 +// stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3;
4474 + /* Noise */
4475 + noise = ioread32(ctl + AGNX_GCR_NOISE0);
4476 + noise += ioread32(ctl + AGNX_GCR_NOISE1);
4477 + noise += ioread32(ctl + AGNX_GCR_NOISE2);
4478 + stat->noise = noise / 3;
4479 + /* Signal quality */
4480 + //snr = stat->ssi - stat->noise;
4481 + if (snr >=0 && snr < 40)
4482 + stat->signal = 5 * snr / 2;
4483 + else if (snr >= 40)
4484 + stat->signal = 100;
4485 + else
4486 + stat->signal = 0;
4487 +
4488 +
4489 + if (hdr->_11b0 && !hdr->_11g0) {
4490 + stat->rate_idx = agnx_plcp_get_bitrate_cck(&hdr->_11b0);
4491 + } else if (!hdr->_11b0 && hdr->_11g0) {
4492 + printk(PFX "RX: Found G mode packet\n");
4493 + stat->rate_idx = agnx_plcp_get_bitrate_ofdm(&hdr->_11g0);
4494 + } else
4495 + agnx_bug("Unknown packets type");
4496 +
4497 +
4498 + stat->band = IEEE80211_BAND_2GHZ;
4499 + stat->freq = agnx_channels[priv->channel - 1].center_freq;
4500 +// stat->antenna = 3;
4501 +// stat->mactime = be32_to_cpu(hdr->time_stamp);
4502 +// stat->channel = priv->channel;
4503 +
4504 +}
4505 +
4506 +static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
4507 + struct sk_buff *skb)
4508 +{
4509 + u16 fctl;
4510 + unsigned int hdrlen;
4511 +
4512 + fctl = le16_to_cpu(ieeehdr->frame_control);
4513 + hdrlen = ieee80211_hdrlen(fctl);
4514 + /* FIXME */
4515 + if (hdrlen < (2+2+6)/*minimum hdr*/ ||
4516 + hdrlen > sizeof(struct ieee80211_mgmt)) {
4517 + printk(KERN_ERR PFX "hdr len is %d\n", hdrlen);
4518 + agnx_bug("Wrong ieee80211 hdr detected");
4519 + }
4520 + skb_push(skb, hdrlen);
4521 + memcpy(skb->data, ieeehdr, hdrlen);
4522 +} /* combine_hdr_frag */
4523 +
4524 +static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr,
4525 + unsigned packet_len)
4526 +{
4527 + if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1){
4528 + printk(PFX "RX: CRC check fail\n");
4529 + goto drop;
4530 + }
4531 + if (packet_len > 2048) {
4532 + printk(PFX "RX: Too long packet detected\n");
4533 + goto drop;
4534 + }
4535 +
4536 + /* FIXME Just usable for Promious Mode, for Manage mode exclude FCS */
4537 +/* if (packet_len - sizeof(*agnxhdr) < FCS_LEN) { */
4538 +/* printk(PFX "RX: Too short packet detected\n"); */
4539 +/* goto drop; */
4540 +/* } */
4541 + return 0;
4542 +drop:
4543 + priv->stats.dot11FCSErrorCount++;
4544 + return -1;
4545 +}
4546 +
4547 +void handle_rx_irq(struct agnx_priv *priv)
4548 +{
4549 + struct ieee80211_rx_status status;
4550 + unsigned int len;
4551 +// AGNX_TRACE;
4552 +
4553 + do {
4554 + struct agnx_desc *desc;
4555 + u32 frag;
4556 + struct agnx_info *info;
4557 + struct agnx_hdr *hdr;
4558 + struct sk_buff *skb;
4559 + unsigned int i = priv->rx.idx % priv->rx.size;
4560 +
4561 + desc = priv->rx.desc + i;
4562 + frag = be32_to_cpu(desc->frag);
4563 + if (frag & OWNER)
4564 + break;
4565 +
4566 + info = priv->rx.info + i;
4567 + skb = info->skb;
4568 + hdr = (struct agnx_hdr *)(skb->data);
4569 +
4570 + len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT;
4571 + if (agnx_packet_check(priv, hdr, len) == -1) {
4572 + rx_desc_reusing(priv, i);
4573 + continue;
4574 + }
4575 + skb_put(skb, len);
4576 +
4577 + do {
4578 + u16 fctl;
4579 + fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control);
4580 + if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)// && !(fctl & IEEE80211_STYPE_BEACON))
4581 + dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX");
4582 + } while (0);
4583 +
4584 + if (hdr->_11b0 && !hdr->_11g0) {
4585 +/* int j; */
4586 +/* u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr) */
4587 +/* ->frame_control); */
4588 +/* if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { */
4589 +/* agnx_print_rx_hdr(hdr); */
4590 +// agnx_print_sta(priv, BSSID_STAID);
4591 +/* for (j = 0; j < 8; j++) */
4592 +/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
4593 +/* } */
4594 +
4595 + get_rx_stats(priv, hdr, &status);
4596 + skb_pull(skb, sizeof(*hdr));
4597 + combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb);
4598 + } else if (!hdr->_11b0 && hdr->_11g0) {
4599 +// int j;
4600 + agnx_print_rx_hdr(hdr);
4601 + agnx_print_sta(priv, BSSID_STAID);
4602 +// for (j = 0; j < 8; j++)
4603 + agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
4604 +
4605 + print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE,
4606 + skb->data, skb->len + 8);
4607 +
4608 +// if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0)
4609 + get_rx_stats(priv, hdr, &status);
4610 + skb_pull(skb, sizeof(*hdr));
4611 + combine_hdr_frag((struct ieee80211_hdr *)
4612 + ((void *)&hdr->mac_hdr), skb);
4613 +// dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G");
4614 + } else
4615 + agnx_bug("Unknown packets type");
4616 + ieee80211_rx_irqsafe(priv->hw, skb, &status);
4617 + rx_desc_reinit(priv, i);
4618 +
4619 + } while ( priv->rx.idx++ );
4620 +} /* handle_rx_irq */
4621 +
4622 +static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
4623 +{
4624 + struct agnx_desc *desc;
4625 + struct agnx_info *info;
4626 + unsigned int idx;
4627 +
4628 + for (idx = ring->idx_sent; idx < ring->idx; idx++) {
4629 + unsigned int i = idx % ring->size;
4630 + u32 frag;
4631 +
4632 + desc = ring->desc + i;
4633 + info = ring->info + i;
4634 +
4635 + frag = be32_to_cpu(desc->frag);
4636 + if (frag & OWNER) {
4637 + if (info->type == HEADER)
4638 + break;
4639 + else
4640 + agnx_bug("TX error");
4641 + }
4642 +
4643 + pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);
4644 +
4645 + do {
4646 +// int j;
4647 + size_t len;
4648 + len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;
4649 + // if (len == 614) {
4650 +// agnx_print_desc(desc);
4651 + if (info->type == PACKET) {
4652 +// agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data);
4653 +/* agnx_print_sta_power(priv, LOCAL_STAID); */
4654 +/* agnx_print_sta(priv, LOCAL_STAID); */
4655 +/* // for (j = 0; j < 8; j++) */
4656 +/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
4657 +// agnx_print_sta_power(priv, BSSID_STAID);
4658 +// agnx_print_sta(priv, BSSID_STAID);
4659 +// for (j = 0; j < 8; j++)
4660 +// agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
4661 + }
4662 +// }
4663 + } while (0);
4664 +
4665 + if (info->type == PACKET) {
4666 +// dump_txm_registers(priv);
4667 +// dump_rxm_registers(priv);
4668 +// dump_bm_registers(priv);
4669 +// dump_cir_registers(priv);
4670 + }
4671 +
4672 + if (info->type == PACKET) {
4673 +// struct ieee80211_hdr *hdr;
4674 + struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);
4675 +
4676 + skb_pull(info->skb, sizeof(struct agnx_hdr));
4677 + memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);
4678 +
4679 +// dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE");
4680 +/* print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */
4681 +/* info->skb->data, info->skb->len); */
4682 +
4683 + if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK))
4684 + txi->flags |= IEEE80211_TX_STAT_ACK;
4685 +
4686 + ieee80211_tx_status_irqsafe(priv->hw, info->skb);
4687 +
4688 +
4689 +/* info->tx_status.queue_number = (ring->size - i) / 2; */
4690 +/* ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */
4691 +/* } else */
4692 +/* dev_kfree_skb_irq(info->skb); */
4693 + }
4694 + memset(desc, 0, sizeof(*desc));
4695 + memset(info, 0, sizeof(*info));
4696 + }
4697 +
4698 + ring->idx_sent = idx;
4699 + /* TODO fill the priv->low_level_stats */
4700 +
4701 + /* ieee80211_wake_queue(priv->hw, 0); */
4702 +}
4703 +
4704 +void handle_txm_irq(struct agnx_priv *priv)
4705 +{
4706 + handle_tx_irq(priv, &priv->txm);
4707 +}
4708 +
4709 +void handle_txd_irq(struct agnx_priv *priv)
4710 +{
4711 + handle_tx_irq(priv, &priv->txd);
4712 +}
4713 +
4714 +void handle_other_irq(struct agnx_priv *priv)
4715 +{
4716 +// void __iomem *ctl = priv->ctl;
4717 + u32 status = priv->irq_status;
4718 + void __iomem *ctl = priv->ctl;
4719 + u32 reg;
4720 +
4721 + if (status & IRQ_TX_BEACON) {
4722 + iowrite32(IRQ_TX_BEACON, ctl + AGNX_INT_STAT);
4723 + printk(PFX "IRQ: TX Beacon control is 0X%.8X\n", ioread32(ctl + AGNX_TXM_BEACON_CTL));
4724 + printk(PFX "IRQ: TX Beacon rx frame num: %d\n", rx_frame_cnt);
4725 + }
4726 + if (status & IRQ_TX_RETRY) {
4727 + reg = ioread32(ctl + AGNX_TXM_RETRYSTAID);
4728 + printk(PFX "IRQ: TX Retry, RETRY STA ID is %x\n", reg);
4729 + }
4730 + if (status & IRQ_TX_ACTIVITY)
4731 + printk(PFX "IRQ: TX Activity\n");
4732 + if (status & IRQ_RX_ACTIVITY)
4733 + printk(PFX "IRQ: RX Activity\n");
4734 + if (status & IRQ_RX_X)
4735 + printk(PFX "IRQ: RX X\n");
4736 + if (status & IRQ_RX_Y) {
4737 + reg = ioread32(ctl + AGNX_INT_MASK);
4738 + reg &= ~IRQ_RX_Y;
4739 + iowrite32(reg, ctl + AGNX_INT_MASK);
4740 + iowrite32(IRQ_RX_Y, ctl + AGNX_INT_STAT);
4741 + printk(PFX "IRQ: RX Y\n");
4742 + }
4743 + if (status & IRQ_RX_HASHHIT) {
4744 + reg = ioread32(ctl + AGNX_INT_MASK);
4745 + reg &= ~IRQ_RX_HASHHIT;
4746 + iowrite32(reg, ctl + AGNX_INT_MASK);
4747 + iowrite32(IRQ_RX_HASHHIT, ctl + AGNX_INT_STAT);
4748 + printk(PFX "IRQ: RX Hash Hit\n");
4749 +
4750 + }
4751 + if (status & IRQ_RX_FRAME) {
4752 + reg = ioread32(ctl + AGNX_INT_MASK);
4753 + reg &= ~IRQ_RX_FRAME;
4754 + iowrite32(reg, ctl + AGNX_INT_MASK);
4755 + iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);
4756 + printk(PFX "IRQ: RX Frame\n");
4757 + rx_frame_cnt++;
4758 + }
4759 + if (status & IRQ_ERR_INT) {
4760 + iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);
4761 +// agnx_hw_reset(priv);
4762 + printk(PFX "IRQ: Error Interrupt\n");
4763 + }
4764 + if (status & IRQ_TX_QUE_FULL)
4765 + printk(PFX "IRQ: TX Workqueue Full\n");
4766 + if (status & IRQ_BANDMAN_ERR)
4767 + printk(PFX "IRQ: Bandwidth Management Error\n");
4768 + if (status & IRQ_TX_DISABLE)
4769 + printk(PFX "IRQ: TX Disable\n");
4770 + if (status & IRQ_RX_IVASESKEY)
4771 + printk(PFX "IRQ: RX Invalid Session Key\n");
4772 + if (status & IRQ_REP_THHIT)
4773 + printk(PFX "IRQ: Replay Threshold Hit\n");
4774 + if (status & IRQ_TIMER1)
4775 + printk(PFX "IRQ: Timer1\n");
4776 + if (status & IRQ_TIMER_CNT)
4777 + printk(PFX "IRQ: Timer Count\n");
4778 + if (status & IRQ_PHY_FASTINT)
4779 + printk(PFX "IRQ: Phy Fast Interrupt\n");
4780 + if (status & IRQ_PHY_SLOWINT)
4781 + printk(PFX "IRQ: Phy Slow Interrupt\n");
4782 + if (status & IRQ_OTHER)
4783 + printk(PFX "IRQ: 0x80000000\n");
4784 +} /* handle_other_irq */
4785 +
4786 +
4787 +static inline void route_flag_set(struct agnx_hdr *txhdr)
4788 +{
4789 +// u32 reg = 0;
4790 +
4791 + /* FIXME */
4792 +/* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
4793 +/* txhdr->reg5 = cpu_to_be32(reg); */
4794 + txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
4795 +// txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18));
4796 +// txhdr->reg5 = cpu_to_be32(0x7 << 0x0);
4797 +}
4798 +
4799 +/* Return 0 if no match */
4800 +static inline unsigned int get_power_level(unsigned int rate, unsigned int antennas_num)
4801 +{
4802 + unsigned int power_level;
4803 +
4804 + switch (rate) {
4805 + case 10:
4806 + case 20:
4807 + case 55:
4808 + case 60:
4809 + case 90:
4810 + case 120: power_level = 22; break;
4811 + case 180: power_level = 19; break;
4812 + case 240: power_level = 18; break;
4813 + case 360: power_level = 16; break;
4814 + case 480: power_level = 15; break;
4815 + case 540: power_level = 14; break;
4816 + default:
4817 + agnx_bug("Error rate setting\n");
4818 + }
4819 +
4820 + if (power_level && (antennas_num == 2))
4821 + power_level -= 3;
4822 +
4823 + return power_level;
4824 +}
4825 +
4826 +static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_info)
4827 +{
4828 + struct agnx_hdr *txhdr = (struct agnx_hdr *)tx_info->skb->data;
4829 + size_t len;
4830 + u16 fc = le16_to_cpu(*(__le16 *)&tx_info->hdr);
4831 + u32 reg;
4832 +
4833 + memset(txhdr, 0, sizeof(*txhdr));
4834 +
4835 +// reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID);
4836 + reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);
4837 + reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);
4838 + txhdr->reg4 = cpu_to_be32(reg);
4839 +
4840 + /* Set the Hardware Sequence Number to 1? */
4841 + reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);
4842 +// reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1);
4843 + reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);
4844 + txhdr->reg1 = cpu_to_be32(reg);
4845 + /* Set the agnx_hdr's MAC header */
4846 + memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);
4847 +
4848 + reg = agnx_set_bits(ACK, ACK_SHIFT, 1);
4849 +// reg = agnx_set_bits(ACK, ACK_SHIFT, 0);
4850 + reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);
4851 +// reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1);
4852 + reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);
4853 + reg |= agnx_set_bits(TM, TM_SHIFT, 0);
4854 + txhdr->reg0 = cpu_to_be32(reg);
4855 +
4856 + /* Set the long and short retry limits */
4857 + txhdr->tx.short_retry_limit = tx_info->txi->control.retry_limit;
4858 + txhdr->tx.long_retry_limit = tx_info->txi->control.retry_limit;
4859 +
4860 + /* FIXME */
4861 + len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;
4862 + if (fc & IEEE80211_FCTL_PROTECTED)
4863 + len += 8;
4864 + len = 2398;
4865 + reg = agnx_set_bits(FRAG_SIZE, FRAG_SIZE_SHIFT, len);
4866 + len = tx_info->skb->len - sizeof(*txhdr);
4867 + reg |= agnx_set_bits(PAYLOAD_LEN, PAYLOAD_LEN_SHIFT, len);
4868 + txhdr->reg3 = cpu_to_be32(reg);
4869 +
4870 + route_flag_set(txhdr);
4871 +} /* fill_hdr */
4872 +
4873 +static void txm_power_set(struct agnx_priv *priv,
4874 + struct ieee80211_tx_info *txi)
4875 +{
4876 + struct agnx_sta_power power;
4877 + u32 reg;
4878 +
4879 + /* FIXME */
4880 + if (txi->tx_rate_idx < 0) {
4881 + /* For B mode Short Preamble */
4882 + reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);
4883 +// control->tx_rate = -control->tx_rate;
4884 + } else
4885 + reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);
4886 +// reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG);
4887 + reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);
4888 + reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);
4889 +// reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15);
4890 + reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);
4891 + /* if rate < 11M set it to 0 */
4892 + reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);
4893 +// reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1);
4894 +// reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1);
4895 +
4896 + power.reg = reg;
4897 +// power.reg = cpu_to_le32(reg);
4898 +
4899 +// set_sta_power(priv, &power, LOCAL_STAID);
4900 + set_sta_power(priv, &power, BSSID_STAID);
4901 +}
4902 +
4903 +static inline int tx_packet_check(struct sk_buff *skb)
4904 +{
4905 + unsigned int ieee_len = ieee80211_get_hdrlen_from_skb(skb);
4906 + if (skb->len > 2048) {
4907 + printk(KERN_ERR PFX "length is %d\n", skb->len);
4908 + agnx_bug("Too long TX skb");
4909 + return -1;
4910 + }
4911 + /* FIXME */
4912 + if (skb->len == ieee_len) {
4913 + printk(PFX "A strange TX packet\n");
4914 + return -1;
4915 + /* tx_faile_irqsafe(); */
4916 + }
4917 + return 0;
4918 +}
4919 +
4920 +static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
4921 + struct agnx_ring *ring)
4922 +{
4923 + struct agnx_desc *hdr_desc, *frag_desc;
4924 + struct agnx_info *hdr_info, *frag_info;
4925 + struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
4926 + unsigned long flags;
4927 + unsigned int i;
4928 +
4929 + spin_lock_irqsave(&priv->lock, flags);
4930 +
4931 + /* The RX interrupt need be Disable until this TX packet
4932 + is handled in the next tx interrupt */
4933 + disable_rx_interrupt(priv);
4934 +
4935 + i = ring->idx;
4936 + ring->idx += 2;
4937 +/* if (priv->txm_idx - priv->txm_idx_sent == AGNX_TXM_RING_SIZE - 2) */
4938 +/* ieee80211_stop_queue(priv->hw, 0); */
4939 +
4940 + /* Set agnx header's info and desc */
4941 + i %= ring->size;
4942 + hdr_desc = ring->desc + i;
4943 + hdr_info = ring->info + i;
4944 + hdr_info->hdr_len = ieee80211_get_hdrlen_from_skb(skb);
4945 + memcpy(&hdr_info->hdr, skb->data, hdr_info->hdr_len);
4946 +
4947 + /* Add the agnx header to the front of the SKB */
4948 + skb_push(skb, sizeof(struct agnx_hdr) - hdr_info->hdr_len);
4949 +
4950 + hdr_info->txi = txi;
4951 + hdr_info->dma_len = sizeof(struct agnx_hdr);
4952 + hdr_info->skb = skb;
4953 + hdr_info->type = HEADER;
4954 + fill_agnx_hdr(priv, hdr_info);
4955 + hdr_info->mapping = pci_map_single(priv->pdev, skb->data,
4956 + hdr_info->dma_len, PCI_DMA_TODEVICE);
4957 + do {
4958 + u32 frag = 0;
4959 + frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 1);
4960 + frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 0);
4961 + frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);
4962 + frag |= agnx_set_bits(FIRST_FRAG_LEN, FIRST_FRAG_LEN_SHIFT, 1);
4963 + frag |= agnx_set_bits(OWNER, OWNER_SHIFT, 1);
4964 + hdr_desc->frag = cpu_to_be32(frag);
4965 + } while (0);
4966 + hdr_desc->dma_addr = cpu_to_be32(hdr_info->mapping);
4967 +
4968 +
4969 + /* Set Frag's info and desc */
4970 + i = (i + 1) % ring->size;
4971 + frag_desc = ring->desc + i;
4972 + frag_info = ring->info + i;
4973 + memcpy(frag_info, hdr_info, sizeof(struct agnx_info));
4974 + frag_info->type = PACKET;
4975 + frag_info->dma_len = skb->len - hdr_info->dma_len;
4976 + frag_info->mapping = pci_map_single(priv->pdev, skb->data + hdr_info->dma_len,
4977 + frag_info->dma_len, PCI_DMA_TODEVICE);
4978 + do {
4979 + u32 frag = 0;
4980 + frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 0);
4981 + frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 1);
4982 + frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);
4983 + frag |= agnx_set_bits(SUB_FRAG_LEN, SUB_FRAG_LEN_SHIFT, frag_info->dma_len);
4984 + frag_desc->frag = cpu_to_be32(frag);
4985 + } while (0);
4986 + frag_desc->dma_addr = cpu_to_be32(frag_info->mapping);
4987 +
4988 + txm_power_set(priv, txi);
4989 +
4990 +/* do { */
4991 +/* int j; */
4992 +/* size_t len; */
4993 +/* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */
4994 +/* // if (len == 614) { */
4995 +/* agnx_print_desc(hdr_desc); */
4996 +/* agnx_print_desc(frag_desc); */
4997 +/* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
4998 +/* agnx_print_sta_power(priv, LOCAL_STAID); */
4999 +/* agnx_print_sta(priv, LOCAL_STAID); */
5000 +/* for (j = 0; j < 8; j++) */
5001 +/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
5002 +/* agnx_print_sta_power(priv, BSSID_STAID); */
5003 +/* agnx_print_sta(priv, BSSID_STAID); */
5004 +/* for (j = 0; j < 8; j++) */
5005 +/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
5006 +/* // } */
5007 +/* } while (0); */
5008 +
5009 + spin_unlock_irqrestore(&priv->lock, flags);
5010 +
5011 + /* FIXME ugly code */
5012 + /* Trigger TXM */
5013 + do {
5014 + u32 reg;
5015 + reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));
5016 + reg |= 0x8;
5017 + iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);
5018 + }while (0);
5019 +
5020 + /* Trigger TXD */
5021 + do {
5022 + u32 reg;
5023 + reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));
5024 + reg |= 0x8;
5025 + iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);
5026 + }while (0);
5027 +
5028 + return 0;
5029 +}
5030 +
5031 +int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb)
5032 +{
5033 + u16 fctl;
5034 +
5035 + if (tx_packet_check(skb))
5036 + return 0;
5037 +
5038 +/* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
5039 +/* skb->data, skb->len); */
5040 +
5041 + fctl = le16_to_cpu(*((__le16 *)skb->data));
5042 +
5043 + if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA )
5044 + return __agnx_tx(priv, skb, &priv->txd);
5045 + else
5046 + return __agnx_tx(priv, skb, &priv->txm);
5047 +}
5048 --- /dev/null
5049 +++ b/drivers/staging/agnx/xmit.h
5050 @@ -0,0 +1,250 @@
5051 +#ifndef AGNX_XMIT_H_
5052 +#define AGNX_XMIT_H_
5053 +
5054 +#include <net/mac80211.h>
5055 +
5056 +struct agnx_priv;
5057 +
5058 +static inline u32 agnx_set_bits(u32 mask, u8 shift, u32 value)
5059 +{
5060 + return (value << shift) & mask;
5061 +}
5062 +
5063 +static inline u32 agnx_get_bits(u32 mask, u8 shift, u32 value)
5064 +{
5065 + return (value & mask) >> shift;
5066 +}
5067 +
5068 +
5069 +struct agnx_rx {
5070 + __be16 rx_packet_duration; /* RX Packet Duration */
5071 + __be16 replay_cnt; /* Replay Count */
5072 +} __attribute__((__packed__));
5073 +
5074 +
5075 +struct agnx_tx {
5076 + u8 long_retry_limit; /* Long Retry Limit */
5077 + u8 short_retry_limit; /* Short Retry Limit */
5078 + u8 long_retry_cnt; /* Long Retry Count */
5079 + u8 short_retry_cnt; /* Short Retry Count */
5080 +} __attribute__((__packed__));
5081 +
5082 +
5083 +/* Copy from bcm43xx */
5084 +#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes]
5085 +#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes)
5086 +#define PAD_BYTES(nr_bytes) P4D_BYTES(__LINE__, nr_bytes)
5087 +
5088 +#define P4D_BIT3S(magic, nr_bits) __be32 __padding##magic:nr_bits
5089 +#define P4D_BITS(line, nr_bits) P4D_BIT3S(line, nr_bits)
5090 +#define PAD_BITS(nr_bits) P4D_BITS(__LINE__, nr_bits)
5091 +
5092 +
5093 +struct agnx_hdr {
5094 + __be32 reg0;
5095 +#define RTS 0x80000000 /* RTS */
5096 +#define RTS_SHIFT 31
5097 +#define MULTICAST 0x40000000 /* multicast */
5098 +#define MULTICAST_SHIFT 30
5099 +#define ACK 0x30000000 /* ACK */
5100 +#define ACK_SHIFT 28
5101 +#define TM 0x08000000 /* TM */
5102 +#define TM_SHIFT 27
5103 +#define RELAY 0x04000000 /* Relay */
5104 +#define RELAY_SHIFT 26
5105 +/* PAD_BITS(4); */
5106 +#define REVISED_FCS 0x00380000 /* revised FCS */
5107 +#define REVISED_FCS_SHIFT 19
5108 +#define NEXT_BUFFER_ADDR 0x0007FFFF /* Next Buffer Address */
5109 +#define NEXT_BUFFER_ADDR_SHIFT 0
5110 +
5111 + __be32 reg1;
5112 +#define MAC_HDR_LEN 0xFC000000 /* MAC Header Length */
5113 +#define MAC_HDR_LEN_SHIFT 26
5114 +#define DURATION_OVERIDE 0x02000000 /* Duration Override */
5115 +#define DURATION_OVERIDE_SHIFT 25
5116 +#define PHY_HDR_OVERIDE 0x01000000 /* PHY Header Override */
5117 +#define PHY_HDR_OVERIDE_SHIFT 24
5118 +#define CRC_FAIL 0x00800000 /* CRC fail */
5119 +#define CRC_FAIL_SHIFT 23
5120 +/* PAD_BITS(1); */
5121 +#define SEQUENCE_NUMBER 0x00200000 /* Sequence Number */
5122 +#define SEQUENCE_NUMBER_SHIFT 21
5123 +/* PAD_BITS(2); */
5124 +#define BUFF_HEAD_ADDR 0x0007FFFF /* Buffer Head Address */
5125 +#define BUFF_HEAD_ADDR_SHIFT 0
5126 +
5127 + __be32 reg2;
5128 +#define PDU_COUNT 0xFC000000 /* PDU Count */
5129 +#define PDU_COUNT_SHIFT 26
5130 +/* PAD_BITS(3); */
5131 +#define WEP_KEY 0x00600000 /* WEP Key # */
5132 +#define WEP_KEY_SHIFT 21
5133 +#define USES_WEP_KEY 0x00100000 /* Uses WEP Key */
5134 +#define USES_WEP_KEY_SHIFT 20
5135 +#define KEEP_ALIVE 0x00080000 /* Keep alive */
5136 +#define KEEP_ALIVE_SHIFT 19
5137 +#define BUFF_TAIL_ADDR 0x0007FFFF /* Buffer Tail Address */
5138 +#define BUFF_TAIL_ADDR_SHIFT 0
5139 +
5140 + __be32 reg3;
5141 +#define CTS_11G 0x80000000 /* CTS in 11g */
5142 +#define CTS_11G_SHIFT 31
5143 +#define RTS_11G 0x40000000 /* RTS in 11g */
5144 +#define RTS_11G_SHIFT 30
5145 +/* PAD_BITS(2); */
5146 +#define FRAG_SIZE 0x0FFF0000 /* fragment size */
5147 +#define FRAG_SIZE_SHIFT 16
5148 +#define PAYLOAD_LEN 0x0000FFF0 /* payload length */
5149 +#define PAYLOAD_LEN_SHIFT 4
5150 +#define FRAG_NUM 0x0000000F /* number of frags */
5151 +#define FRAG_NUM_SHIFT 0
5152 +
5153 + __be32 reg4;
5154 +/* PAD_BITS(4); */
5155 +#define RELAY_STAID 0x0FFF0000 /* relayStald */
5156 +#define RELAY_STAID_SHIFT 16
5157 +#define STATION_ID 0x0000FFF0 /* Station ID */
5158 +#define STATION_ID_SHIFT 4
5159 +#define WORKQUEUE_ID 0x0000000F /* Workqueue ID */
5160 +#define WORKQUEUE_ID_SHIFT 0
5161 +
5162 + /* FIXME this register maybe is LE? */
5163 + __be32 reg5;
5164 +/* PAD_BITS(4); */
5165 +#define ROUTE_HOST 0x0F000000
5166 +#define ROUTE_HOST_SHIFT 24
5167 +#define ROUTE_CARD_CPU 0x00F00000
5168 +#define ROUTE_CARD_CPU_SHIFT 20
5169 +#define ROUTE_ENCRYPTION 0x000F0000
5170 +#define ROUTE_ENCRYPTION_SHIFT 16
5171 +#define ROUTE_TX 0x0000F000
5172 +#define ROUTE_TX_SHIFT 12
5173 +#define ROUTE_RX1 0x00000F00
5174 +#define ROUTE_RX1_SHIFT 8
5175 +#define ROUTE_RX2 0x000000F0
5176 +#define ROUTE_RX2_SHIFT 4
5177 +#define ROUTE_COMPRESSION 0x0000000F
5178 +#define ROUTE_COMPRESSION_SHIFT 0
5179 +
5180 + __be32 _11g0; /* 11g */
5181 + __be32 _11g1; /* 11g */
5182 + __be32 _11b0; /* 11b */
5183 + __be32 _11b1; /* 11b */
5184 + u8 mac_hdr[32]; /* MAC header */
5185 +
5186 + __be16 rts_duration; /* RTS duration */
5187 + __be16 last_duration; /* Last duration */
5188 + __be16 sec_last_duration; /* Second to Last duration */
5189 + __be16 other_duration; /* Other duration */
5190 + __be16 tx_last_duration; /* TX Last duration */
5191 + __be16 tx_other_duration; /* TX Other Duration */
5192 + __be16 last_11g_len; /* Length of last 11g */
5193 + __be16 other_11g_len; /* Lenght of other 11g */
5194 +
5195 + __be16 last_11b_len; /* Length of last 11b */
5196 + __be16 other_11b_len; /* Lenght of other 11b */
5197 +
5198 +
5199 + __be16 reg6;
5200 +#define MBF 0xF000 /* mbf */
5201 +#define MBF_SHIFT 12
5202 +#define RSVD4 0x0FFF /* rsvd4 */
5203 +#define RSVD4_SHIFT 0
5204 +
5205 + __be16 rx_frag_stat; /* RX fragmentation status */
5206 +
5207 + __be32 time_stamp; /* TimeStamp */
5208 + __be32 phy_stats_hi; /* PHY stats hi */
5209 + __be32 phy_stats_lo; /* PHY stats lo */
5210 + __be32 mic_key0; /* MIC key 0 */
5211 + __be32 mic_key1; /* MIC key 1 */
5212 +
5213 + union { /* RX/TX Union */
5214 + struct agnx_rx rx;
5215 + struct agnx_tx tx;
5216 + };
5217 +
5218 + u8 rx_channel; /* Recieve Channel */
5219 + PAD_BYTES(3);
5220 +
5221 + u8 reserved[4];
5222 +} __attribute__((__packed__));
5223 +
5224 +
5225 +struct agnx_desc {
5226 +#define PACKET_LEN 0xFFF00000
5227 +#define PACKET_LEN_SHIFT 20
5228 +/* ------------------------------------------------ */
5229 +#define FIRST_PACKET_MASK 0x00080000
5230 +#define FIRST_PACKET_MASK_SHIFT 19
5231 +#define FIRST_RESERV2 0x00040000
5232 +#define FIRST_RESERV2_SHIFT 18
5233 +#define FIRST_TKIP_ERROR 0x00020000
5234 +#define FIRST_TKIP_ERROR_SHIFT 17
5235 +#define FIRST_TKIP_PACKET 0x00010000
5236 +#define FIRST_TKIP_PACKET_SHIFT 16
5237 +#define FIRST_RESERV1 0x0000F000
5238 +#define FIRST_RESERV1_SHIFT 12
5239 +#define FIRST_FRAG_LEN 0x00000FF8
5240 +#define FIRST_FRAG_LEN_SHIFT 3
5241 +/* ------------------------------------------------ */
5242 +#define SUB_RESERV2 0x000c0000
5243 +#define SUB_RESERV2_SHIFT 18
5244 +#define SUB_TKIP_ERROR 0x00020000
5245 +#define SUB_TKIP_ERROR_SHIFT 17
5246 +#define SUB_TKIP_PACKET 0x00010000
5247 +#define SUB_TKIP_PACKET_SHIFT 16
5248 +#define SUB_RESERV1 0x00008000
5249 +#define SUB_RESERV1_SHIFT 15
5250 +#define SUB_FRAG_LEN 0x00007FF8
5251 +#define SUB_FRAG_LEN_SHIFT 3
5252 +/* ------------------------------------------------ */
5253 +#define FIRST_FRAG 0x00000004
5254 +#define FIRST_FRAG_SHIFT 2
5255 +#define LAST_FRAG 0x00000002
5256 +#define LAST_FRAG_SHIFT 1
5257 +#define OWNER 0x00000001
5258 +#define OWNER_SHIFT 0
5259 + __be32 frag;
5260 + __be32 dma_addr;
5261 +} __attribute__((__packed__));
5262 +
5263 +enum {HEADER, PACKET};
5264 +
5265 +struct agnx_info {
5266 + struct sk_buff *skb;
5267 + dma_addr_t mapping;
5268 + u32 dma_len; /* dma buffer len */
5269 + /* Below fields only usful for tx */
5270 + u32 hdr_len; /* ieee80211 header length */
5271 + unsigned int type;
5272 + struct ieee80211_tx_info *txi;
5273 + struct ieee80211_hdr hdr;
5274 +};
5275 +
5276 +
5277 +struct agnx_ring {
5278 + struct agnx_desc *desc;
5279 + dma_addr_t dma;
5280 + struct agnx_info *info;
5281 + /* Will lead to overflow when sent packet number enough? */
5282 + unsigned int idx;
5283 + unsigned int idx_sent; /* only usful for txd and txm */
5284 + unsigned int size;
5285 +};
5286 +
5287 +#define AGNX_RX_RING_SIZE 128
5288 +#define AGNX_TXD_RING_SIZE 256
5289 +#define AGNX_TXM_RING_SIZE 128
5290 +
5291 +void disable_rx_interrupt(struct agnx_priv *priv);
5292 +void enable_rx_interrupt(struct agnx_priv *priv);
5293 +int fill_rings(struct agnx_priv *priv);
5294 +void unfill_rings(struct agnx_priv *priv);
5295 +void handle_rx_irq(struct agnx_priv *priv);
5296 +void handle_txd_irq(struct agnx_priv *priv);
5297 +void handle_txm_irq(struct agnx_priv *priv);
5298 +void handle_other_irq(struct agnx_priv *priv);
5299 +int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb);
5300 +#endif /* AGNX_XMIT_H_ */
5301 --- a/drivers/staging/Kconfig
5302 +++ b/drivers/staging/Kconfig
5303 @@ -43,4 +43,6 @@ source "drivers/staging/echo/Kconfig"
5304
5305 source "drivers/staging/at76_usb/Kconfig"
5306
5307 +source "drivers/staging/agnx/Kconfig"
5308 +
5309 endif # STAGING
5310 --- a/drivers/staging/Makefile
5311 +++ b/drivers/staging/Makefile
5312 @@ -13,3 +13,4 @@ obj-$(CONFIG_W35UND) += winbond/
5313 obj-$(CONFIG_PRISM2_USB) += wlan-ng/
5314 obj-$(CONFIG_ECHO) += echo/
5315 obj-$(CONFIG_USB_ATMEL) += at76_usb/
5316 +obj-$(CONFIG_AGNX) += agnx/