blob: d3ac675e45bd7bbd8280c595b53dec1399156c31 [file] [log] [blame]
Li YanBo0f22aab2008-10-27 20:32:57 -07001#include <linux/delay.h>
2#include <linux/etherdevice.h>
3#include "phy.h"
4#include "sta.h"
5#include "debug.h"
6
7void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
8{
9 void __iomem *ctl = priv->ctl;
10
11 reglo &= 0xFFFF;
12 reglo |= 0x30000000;
13 reglo |= 0x40000000; /* Set status busy */
14 reglo |= sta_id << 16;
15
16 iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
17 iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
18 iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
19
20 reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
21 reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
22 printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
23}
24
25void hash_write(struct agnx_priv *priv, u8 *mac_addr, u8 sta_id)
26{
27 void __iomem *ctl = priv->ctl;
28 u32 reghi, reglo;
29
30 if (!is_valid_ether_addr(mac_addr))
31 printk(KERN_WARNING PFX "Update hash table: Invalid hwaddr!\n");
32
33 reghi = mac_addr[0] << 24 | mac_addr[1] << 16 | mac_addr[2] << 8 | mac_addr[3];
34 reglo = mac_addr[4] << 8 | mac_addr[5];
35 reglo |= 0x10000000; /* Set hash commmand */
36 reglo |= 0x40000000; /* Set status busy */
37 reglo |= sta_id << 16;
38
39 iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
40 iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
41 iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
42
43 reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
44 if (!(reglo & 0x80000000))
45 printk(KERN_WARNING PFX "Update hash table failed\n");
46}
47
48void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
49{
50 void __iomem *ctl = priv->ctl;
51
52 reglo &= 0xFFFF;
53 reglo |= 0x20000000;
54 reglo |= 0x40000000; /* Set status busy */
55 reglo |= sta_id << 16;
56
57 iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
58 iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
59 iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
60 reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
61
62 reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
63 printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
64
65}
66
67void hash_dump(struct agnx_priv *priv, u8 sta_id)
68{
69 void __iomem *ctl = priv->ctl;
70 u32 reghi, reglo;
71
72 reglo = 0x0; /* dump command */
73 reglo|= 0x40000000; /* status bit */
74 iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
75 iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA);
76
77 udelay(80);
78
79 reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
80 reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
81 printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo);
82 reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG);
83 printk(PFX "hash flag is : %.8x\n", reghi);
84 reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_MST);
85 reglo = ioread32(ctl + AGNX_RXM_HASH_DUMP_LST);
86 printk(PFX "hash dump mst lst: %.8x%.8x\n", reghi, reglo);
87 reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_DATA);
88 printk(PFX "hash dump data: %.8x\n", reghi);
89}
90
91void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
92{
93 void __iomem *ctl = priv->ctl;
94 memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
95 sizeof(*power));
96}
97
98inline void
99set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
100{
101 void __iomem *ctl = priv->ctl;
102 /* FIXME 2. Write Template to offset + station number */
103 memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
104 power, sizeof(*power));
105}
106
107
108void get_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
109 unsigned int sta_idx, unsigned int wq_idx)
110{
111 void __iomem *data = priv->data;
112 memcpy_fromio(tx_wq, data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx +
113 sizeof(*tx_wq) * wq_idx, sizeof(*tx_wq));
114
115}
116
117inline void set_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
118 unsigned int sta_idx, unsigned int wq_idx)
119{
120 void __iomem *data = priv->data;
121 memcpy_toio(data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx +
122 sizeof(*tx_wq) * wq_idx, tx_wq, sizeof(*tx_wq));
123}
124
125
126void get_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx)
127{
128 void __iomem *data = priv->data;
129
130 memcpy_fromio(sta, data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
131 sizeof(*sta));
132}
133
134inline void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx)
135{
136 void __iomem *data = priv->data;
137
138 memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
139 sta, sizeof(*sta));
140}
141
142/* FIXME */
143void sta_power_init(struct agnx_priv *priv, unsigned int sta_idx)
144{
145 struct agnx_sta_power power;
146 u32 reg;
147 AGNX_TRACE;
148
149 memset(&power, 0, sizeof(power));
150 reg = agnx_set_bits(EDCF, EDCF_SHIFT, 0x1);
151 power.reg = cpu_to_le32(reg);
152 set_sta_power(priv, &power, sta_idx);
153 udelay(40);
154} /* add_power_template */
155
156
157/* @num: The #number of station that is visible to the card */
158static void sta_tx_workqueue_init(struct agnx_priv *priv, unsigned int sta_idx)
159{
160 struct agnx_sta_tx_wq tx_wq;
161 u32 reg;
162 unsigned int i;
163
164 memset(&tx_wq, 0, sizeof(tx_wq));
165
166 reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1);
167 reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1);
168// reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0);
169 tx_wq.reg2 |= cpu_to_le32(reg);
170
171 /* Suppose all 8 traffic class are used */
172 for (i = 0; i < STA_TX_WQ_NUM; i++)
173 set_sta_tx_wq(priv, &tx_wq, sta_idx, i);
174} /* sta_tx_workqueue_init */
175
176
177static void sta_traffic_init(struct agnx_sta_traffic *traffic)
178{
179 u32 reg;
180 memset(traffic, 0, sizeof(*traffic));
181
182 reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1);
183 reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1);
184// reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1);
185 traffic->reg0 = cpu_to_le32(reg);
186
187 /* 3. setting RX Sequence Number to 4095 */
188 reg = agnx_set_bits(RX_SEQUENCE_NUM, RX_SEQUENCE_NUM_SHIFT, 4095);
189 traffic->reg1 = cpu_to_le32(reg);
190}
191
192
193/* @num: The #number of station that is visible to the card */
194void sta_init(struct agnx_priv *priv, unsigned int sta_idx)
195{
196 /* FIXME the length of sta is 256 bytes Is that
197 * dangerous to stack overflow? */
198 struct agnx_sta sta;
199 u32 reg;
200 int i;
201
202 memset(&sta, 0, sizeof(sta));
203 /* Set valid to 1 */
204 reg = agnx_set_bits(STATION_VALID, STATION_VALID_SHIFT, 1);
205 /* Set Enable Concatenation to 0 (?) */
206 reg |= agnx_set_bits(ENABLE_CONCATENATION, ENABLE_CONCATENATION_SHIFT, 0);
207 /* Set Enable Decompression to 0 (?) */
208 reg |= agnx_set_bits(ENABLE_DECOMPRESSION, ENABLE_DECOMPRESSION_SHIFT, 0);
209 sta.reg = cpu_to_le32(reg);
210
211 /* Initialize each of the Traffic Class Structures by: */
212 for (i = 0; i < 8; i++)
213 sta_traffic_init(sta.traffic + i);
214
215 set_sta(priv, &sta, sta_idx);
216 sta_tx_workqueue_init(priv, sta_idx);
217} /* sta_descriptor_init */
218
219