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
, 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
= 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
);
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
);
91 void get_sta_power(struct agnx_priv
*priv
, struct agnx_sta_power
*power
, unsigned int sta_idx
)
93 void __iomem
*ctl
= priv
->ctl
;
94 memcpy_fromio(power
, ctl
+ AGNX_TXM_STAPOWTEMP
+ sizeof(*power
) * sta_idx
,
99 set_sta_power(struct agnx_priv
*priv
, struct agnx_sta_power
*power
, unsigned int sta_idx
)
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
));
108 void get_sta_tx_wq(struct agnx_priv
*priv
, struct agnx_sta_tx_wq
*tx_wq
,
109 unsigned int sta_idx
, unsigned int wq_idx
)
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
));
117 inline 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
)
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
));
126 void get_sta(struct agnx_priv
*priv
, struct agnx_sta
*sta
, unsigned int sta_idx
)
128 void __iomem
*data
= priv
->data
;
130 memcpy_fromio(sta
, data
+ AGNX_PDUPOOL
+ sizeof(*sta
) * sta_idx
,
134 inline void set_sta(struct agnx_priv
*priv
, struct agnx_sta
*sta
, unsigned int sta_idx
)
136 void __iomem
*data
= priv
->data
;
138 memcpy_toio(data
+ AGNX_PDUPOOL
+ sizeof(*sta
) * sta_idx
,
143 void sta_power_init(struct agnx_priv
*priv
, unsigned int sta_idx
)
145 struct agnx_sta_power power
;
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
);
154 } /* add_power_template */
157 /* @num: The #number of station that is visible to the card */
158 static void sta_tx_workqueue_init(struct agnx_priv
*priv
, unsigned int sta_idx
)
160 struct agnx_sta_tx_wq tx_wq
;
164 memset(&tx_wq
, 0, sizeof(tx_wq
));
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
);
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 */
177 static void sta_traffic_init(struct agnx_sta_traffic
*traffic
)
180 memset(traffic
, 0, sizeof(*traffic
));
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
);
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
);
193 /* @num: The #number of station that is visible to the card */
194 void sta_init(struct agnx_priv
*priv
, unsigned int sta_idx
)
196 /* FIXME the length of sta is 256 bytes Is that
197 * dangerous to stack overflow? */
202 memset(&sta
, 0, sizeof(sta
));
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
);
211 /* Initialize each of the Traffic Class Structures by: */
212 for (i
= 0; i
< 8; i
++)
213 sta_traffic_init(sta
.traffic
+ i
);
215 set_sta(priv
, &sta
, sta_idx
);
216 sta_tx_workqueue_init(priv
, sta_idx
);
217 } /* sta_descriptor_init */