]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.drivers/staging-add-agnx-wireless-driver.patch
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / staging-add-agnx-wireless-driver.patch
CommitLineData
2cb7cef9
BS
1From e983cf526bfd8ea56b72490f7449c65ee4dd0a16 Mon Sep 17 00:00:00 2001
2From: Li YanBo <dreamfly281@gmail.com>
3Date: Mon, 27 Oct 2008 20:32:57 -0700
4Subject: Staging: add agnx wireless driver
5Patch-mainline: 2.6.28
6
7From: Li YanBo <dreamfly281@gmail.com>
8
9This driver is for the Airgo AGNX00 wireless chip.
10
11From: Li YanBo <dreamfly281@gmail.com>
12Signed-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/