1 #include <linux/delay.h>
2 #include <linux/etherdevice.h>
7 void hash_read(struct agnx_priv
*priv
, u32 reghi
, u32 reglo
, u8 sta_id
)
9 void __iomem
*ctl
= priv
->ctl
;
13 reglo
|= 0x40000000; /* Set status busy */
14 reglo
|= sta_id
<< 16;
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
);
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
);
25 void hash_write(struct agnx_priv
*priv
, const u8
*mac_addr
, u8 sta_id
)
27 void __iomem
*ctl
= priv
->ctl
;
30 if (!is_valid_ether_addr(mac_addr
))
31 printk(KERN_WARNING PFX
"Update hash table: Invalid hwaddr!\n");
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;
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
);
43 reglo
= ioread32(ctl
+ AGNX_RXM_HASH_CMD_LOW
);
44 if (!(reglo
& 0x80000000))
45 printk(KERN_WARNING PFX
"Update hash table failed\n");
48 void hash_delete(struct agnx_priv
*priv
, u32 reghi
, u32 reglo
, u8 sta_id
)
50 void __iomem
*ctl
= priv
->ctl
;
54 reglo
|= 0x40000000; /* Set status busy */
55 reglo
|= sta_id
<< 16;
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
);
62 reglo
= ioread32(ctl
+ AGNX_RXM_HASH_CMD_LOW
);
63 printk(PFX
"RX hash cmd are : %.8x%.8x\n", reghi
, reglo
);
67 void hash_dump(struct agnx_priv
*priv
, u8 sta_id
)
69 void __iomem
*ctl
= priv
->ctl
;
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
);
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
);
90 void get_sta_power(struct agnx_priv
*priv
, struct agnx_sta_power
*power
, unsigned int sta_idx
)
92 void __iomem
*ctl
= priv
->ctl
;
93 memcpy_fromio(power
, ctl
+ AGNX_TXM_STAPOWTEMP
+ sizeof(*power
) * sta_idx
,
98 set_sta_power(struct agnx_priv
*priv
, struct agnx_sta_power
*power
, unsigned int sta_idx
)
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
));
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
)
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
));
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
)
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
));
125 void get_sta(struct agnx_priv
*priv
, struct agnx_sta
*sta
, unsigned int sta_idx
)
127 void __iomem
*data
= priv
->data
;
129 memcpy_fromio(sta
, data
+ AGNX_PDUPOOL
+ sizeof(*sta
) * sta_idx
,
133 inline void set_sta(struct agnx_priv
*priv
, struct agnx_sta
*sta
, unsigned int sta_idx
)
135 void __iomem
*data
= priv
->data
;
137 memcpy_toio(data
+ AGNX_PDUPOOL
+ sizeof(*sta
) * sta_idx
,
142 void sta_power_init(struct agnx_priv
*priv
, unsigned int sta_idx
)
144 struct agnx_sta_power power
;
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
);
153 } /* add_power_template */
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
)
159 struct agnx_sta_tx_wq tx_wq
;
163 memset(&tx_wq
, 0, sizeof(tx_wq
));
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
);
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 */
176 static void sta_traffic_init(struct agnx_sta_traffic
*traffic
)
179 memset(traffic
, 0, sizeof(*traffic
));
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
);
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
);
192 /* @num: The #number of station that is visible to the card */
193 void sta_init(struct agnx_priv
*priv
, unsigned int sta_idx
)
195 /* FIXME the length of sta is 256 bytes Is that
196 * dangerous to stack overflow? */
201 memset(&sta
, 0, sizeof(sta
));
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
);
210 /* Initialize each of the Traffic Class Structures by: */
211 for (i
= 0; i
< 8; i
++)
212 sta_traffic_init(sta
.traffic
+ i
);
214 set_sta(priv
, &sta
, sta_idx
);
215 sta_tx_workqueue_init(priv
, sta_idx
);
216 } /* sta_descriptor_init */