Merge branch 'for-2.6.30' of git://linux-nfs.org/~bfields/linux
[linux-2.6] / drivers / staging / agnx / sta.c
1 #include <linux/delay.h>
2 #include <linux/etherdevice.h>
3 #include "phy.h"
4 #include "sta.h"
5 #include "debug.h"
6
7 void 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
25 void 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
48 void 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
67 void hash_dump(struct agnx_priv *priv, u8 sta_id)
68 {
69         void __iomem *ctl = priv->ctl;
70         u32 reghi, reglo;
71
72         reglo = 0x40000000;     /* status bit */
73         iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
74         iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA);
75
76         udelay(80);
77
78         reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
79         reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
80         printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo);
81         reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG);
82         printk(PFX "hash flag is : %.8x\n", reghi);
83         reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_MST);
84         reglo = ioread32(ctl + AGNX_RXM_HASH_DUMP_LST);
85         printk(PFX "hash dump mst lst: %.8x%.8x\n", reghi, reglo);
86         reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_DATA);
87         printk(PFX "hash dump data: %.8x\n", reghi);
88 }
89
90 void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
91 {
92         void __iomem *ctl = priv->ctl;
93         memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
94                       sizeof(*power));
95 }
96
97 inline void
98 set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
99 {
100         void __iomem *ctl = priv->ctl;
101         /* FIXME   2. Write Template to offset + station number  */
102         memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
103                     power, sizeof(*power));
104 }
105
106
107 void get_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
108                    unsigned int sta_idx, unsigned int wq_idx)
109 {
110         void __iomem *data = priv->data;
111         memcpy_fromio(tx_wq, data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx +
112                       sizeof(*tx_wq) * wq_idx,  sizeof(*tx_wq));
113
114 }
115
116 inline void set_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
117                    unsigned int sta_idx, unsigned int wq_idx)
118 {
119         void __iomem *data = priv->data;
120         memcpy_toio(data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx +
121                     sizeof(*tx_wq) * wq_idx, tx_wq, sizeof(*tx_wq));
122 }
123
124
125 void get_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx)
126 {
127         void __iomem *data = priv->data;
128
129         memcpy_fromio(sta, data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
130                       sizeof(*sta));
131 }
132
133 inline void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx)
134 {
135         void __iomem *data = priv->data;
136
137         memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
138                     sta, sizeof(*sta));
139 }
140
141 /* FIXME */
142 void sta_power_init(struct agnx_priv *priv, unsigned int sta_idx)
143 {
144         struct agnx_sta_power power;
145         u32 reg;
146         AGNX_TRACE;
147
148         memset(&power, 0, sizeof(power));
149         reg = agnx_set_bits(EDCF, EDCF_SHIFT, 0x1);
150         power.reg = cpu_to_le32(reg);
151         set_sta_power(priv, &power, sta_idx);
152         udelay(40);
153 } /* add_power_template */
154
155
156 /* @num: The #number of station that is visible to the card */
157 static void sta_tx_workqueue_init(struct agnx_priv *priv, unsigned int sta_idx)
158 {
159         struct agnx_sta_tx_wq tx_wq;
160         u32 reg;
161         unsigned int i;
162
163         memset(&tx_wq, 0, sizeof(tx_wq));
164
165         reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1);
166         reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1);
167 /*      reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0); */
168         tx_wq.reg2 |= cpu_to_le32(reg);
169
170         /* Suppose all 8 traffic class are used */
171         for (i = 0; i < STA_TX_WQ_NUM; i++)
172                 set_sta_tx_wq(priv, &tx_wq, sta_idx, i);
173 } /* sta_tx_workqueue_init */
174
175
176 static void sta_traffic_init(struct agnx_sta_traffic *traffic)
177 {
178         u32 reg;
179         memset(traffic, 0, sizeof(*traffic));
180
181         reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1);
182         reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1);
183 /*      reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1); */
184         traffic->reg0 = cpu_to_le32(reg);
185
186         /*      3. setting RX Sequence Number to 4095 */
187         reg = agnx_set_bits(RX_SEQUENCE_NUM, RX_SEQUENCE_NUM_SHIFT, 4095);
188         traffic->reg1 = cpu_to_le32(reg);
189 }
190
191
192 /* @num: The #number of station that is visible to the card */
193 void sta_init(struct agnx_priv *priv, unsigned int sta_idx)
194 {
195         /* FIXME the length of sta is 256 bytes Is that
196          * dangerous to stack overflow? */
197         struct agnx_sta sta;
198         u32 reg;
199         int i;
200
201         memset(&sta, 0, sizeof(sta));
202         /* Set valid to 1 */
203         reg = agnx_set_bits(STATION_VALID, STATION_VALID_SHIFT, 1);
204         /* Set Enable Concatenation to 0 (?) */
205         reg |= agnx_set_bits(ENABLE_CONCATENATION, ENABLE_CONCATENATION_SHIFT, 0);
206         /* Set Enable Decompression to 0 (?) */
207         reg |= agnx_set_bits(ENABLE_DECOMPRESSION, ENABLE_DECOMPRESSION_SHIFT, 0);
208         sta.reg = cpu_to_le32(reg);
209
210         /* Initialize each of the Traffic Class Structures by: */
211         for (i = 0; i < 8; i++)
212                 sta_traffic_init(sta.traffic + i);
213
214         set_sta(priv, &sta, sta_idx);
215         sta_tx_workqueue_init(priv, sta_idx);
216 } /* sta_descriptor_init */
217
218