diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/tokenring/smctr.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/net/tokenring/smctr.c')
-rw-r--r-- | drivers/net/tokenring/smctr.c | 5742 |
1 files changed, 5742 insertions, 0 deletions
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c new file mode 100644 index 000000000000..5c8aeacb8318 --- /dev/null +++ b/drivers/net/tokenring/smctr.c | |||
@@ -0,0 +1,5742 @@ | |||
1 | /* | ||
2 | * smctr.c: A network driver for the SMC Token Ring Adapters. | ||
3 | * | ||
4 | * Written by Jay Schulist <jschlst@samba.org> | ||
5 | * | ||
6 | * This software may be used and distributed according to the terms | ||
7 | * of the GNU General Public License, incorporated herein by reference. | ||
8 | * | ||
9 | * This device driver works with the following SMC adapters: | ||
10 | * - SMC TokenCard Elite (8115T, chips 825/584) | ||
11 | * - SMC TokenCard Elite/A MCA (8115T/A, chips 825/594) | ||
12 | * | ||
13 | * Source(s): | ||
14 | * - SMC TokenCard SDK. | ||
15 | * | ||
16 | * Maintainer(s): | ||
17 | * JS Jay Schulist <jschlst@samba.org> | ||
18 | * | ||
19 | * Changes: | ||
20 | * 07102000 JS Fixed a timing problem in smctr_wait_cmd(); | ||
21 | * Also added a bit more discriptive error msgs. | ||
22 | * 07122000 JS Fixed problem with detecting a card with | ||
23 | * module io/irq/mem specified. | ||
24 | * | ||
25 | * To do: | ||
26 | * 1. Multicast support. | ||
27 | * | ||
28 | * Initial 2.5 cleanup Alan Cox <alan@redhat.com> 2002/10/28 | ||
29 | */ | ||
30 | |||
31 | #include <linux/module.h> | ||
32 | #include <linux/config.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/types.h> | ||
35 | #include <linux/fcntl.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/ptrace.h> | ||
38 | #include <linux/ioport.h> | ||
39 | #include <linux/in.h> | ||
40 | #include <linux/slab.h> | ||
41 | #include <linux/string.h> | ||
42 | #include <linux/time.h> | ||
43 | #include <linux/errno.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/mca-legacy.h> | ||
47 | #include <linux/delay.h> | ||
48 | #include <linux/netdevice.h> | ||
49 | #include <linux/etherdevice.h> | ||
50 | #include <linux/skbuff.h> | ||
51 | #include <linux/trdevice.h> | ||
52 | #include <linux/bitops.h> | ||
53 | |||
54 | #include <asm/system.h> | ||
55 | #include <asm/io.h> | ||
56 | #include <asm/dma.h> | ||
57 | #include <asm/irq.h> | ||
58 | |||
59 | #if BITS_PER_LONG == 64 | ||
60 | #error FIXME: driver does not support 64-bit platforms | ||
61 | #endif | ||
62 | |||
63 | #include "smctr.h" /* Our Stuff */ | ||
64 | #include "smctr_firmware.h" /* SMC adapter firmware */ | ||
65 | |||
66 | static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n"; | ||
67 | static const char cardname[] = "smctr"; | ||
68 | |||
69 | |||
70 | #define SMCTR_IO_EXTENT 20 | ||
71 | |||
72 | #ifdef CONFIG_MCA_LEGACY | ||
73 | static unsigned int smctr_posid = 0x6ec6; | ||
74 | #endif | ||
75 | |||
76 | static int ringspeed; | ||
77 | |||
78 | /* SMC Name of the Adapter. */ | ||
79 | static char smctr_name[] = "SMC TokenCard"; | ||
80 | char *smctr_model = "Unknown"; | ||
81 | |||
82 | /* Use 0 for production, 1 for verification, 2 for debug, and | ||
83 | * 3 for very verbose debug. | ||
84 | */ | ||
85 | #ifndef SMCTR_DEBUG | ||
86 | #define SMCTR_DEBUG 1 | ||
87 | #endif | ||
88 | static unsigned int smctr_debug = SMCTR_DEBUG; | ||
89 | |||
90 | /* smctr.c prototypes and functions are arranged alphabeticly | ||
91 | * for clearity, maintainability and pure old fashion fun. | ||
92 | */ | ||
93 | /* A */ | ||
94 | static int smctr_alloc_shared_memory(struct net_device *dev); | ||
95 | |||
96 | /* B */ | ||
97 | static int smctr_bypass_state(struct net_device *dev); | ||
98 | |||
99 | /* C */ | ||
100 | static int smctr_checksum_firmware(struct net_device *dev); | ||
101 | static int __init smctr_chk_isa(struct net_device *dev); | ||
102 | static int smctr_chg_rx_mask(struct net_device *dev); | ||
103 | static int smctr_clear_int(struct net_device *dev); | ||
104 | static int smctr_clear_trc_reset(int ioaddr); | ||
105 | static int smctr_close(struct net_device *dev); | ||
106 | |||
107 | /* D */ | ||
108 | static int smctr_decode_firmware(struct net_device *dev); | ||
109 | static int smctr_disable_16bit(struct net_device *dev); | ||
110 | static int smctr_disable_adapter_ctrl_store(struct net_device *dev); | ||
111 | static int smctr_disable_bic_int(struct net_device *dev); | ||
112 | |||
113 | /* E */ | ||
114 | static int smctr_enable_16bit(struct net_device *dev); | ||
115 | static int smctr_enable_adapter_ctrl_store(struct net_device *dev); | ||
116 | static int smctr_enable_adapter_ram(struct net_device *dev); | ||
117 | static int smctr_enable_bic_int(struct net_device *dev); | ||
118 | |||
119 | /* G */ | ||
120 | static int __init smctr_get_boardid(struct net_device *dev, int mca); | ||
121 | static int smctr_get_group_address(struct net_device *dev); | ||
122 | static int smctr_get_functional_address(struct net_device *dev); | ||
123 | static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev); | ||
124 | static int smctr_get_physical_drop_number(struct net_device *dev); | ||
125 | static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue); | ||
126 | static int smctr_get_station_id(struct net_device *dev); | ||
127 | static struct net_device_stats *smctr_get_stats(struct net_device *dev); | ||
128 | static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, | ||
129 | __u16 bytes_count); | ||
130 | static int smctr_get_upstream_neighbor_addr(struct net_device *dev); | ||
131 | |||
132 | /* H */ | ||
133 | static int smctr_hardware_send_packet(struct net_device *dev, | ||
134 | struct net_local *tp); | ||
135 | /* I */ | ||
136 | static int smctr_init_acbs(struct net_device *dev); | ||
137 | static int smctr_init_adapter(struct net_device *dev); | ||
138 | static int smctr_init_card_real(struct net_device *dev); | ||
139 | static int smctr_init_rx_bdbs(struct net_device *dev); | ||
140 | static int smctr_init_rx_fcbs(struct net_device *dev); | ||
141 | static int smctr_init_shared_memory(struct net_device *dev); | ||
142 | static int smctr_init_tx_bdbs(struct net_device *dev); | ||
143 | static int smctr_init_tx_fcbs(struct net_device *dev); | ||
144 | static int smctr_internal_self_test(struct net_device *dev); | ||
145 | static irqreturn_t smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs); | ||
146 | static int smctr_issue_enable_int_cmd(struct net_device *dev, | ||
147 | __u16 interrupt_enable_mask); | ||
148 | static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, | ||
149 | __u16 ibits); | ||
150 | static int smctr_issue_init_timers_cmd(struct net_device *dev); | ||
151 | static int smctr_issue_init_txrx_cmd(struct net_device *dev); | ||
152 | static int smctr_issue_insert_cmd(struct net_device *dev); | ||
153 | static int smctr_issue_read_ring_status_cmd(struct net_device *dev); | ||
154 | static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt); | ||
155 | static int smctr_issue_remove_cmd(struct net_device *dev); | ||
156 | static int smctr_issue_resume_acb_cmd(struct net_device *dev); | ||
157 | static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue); | ||
158 | static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue); | ||
159 | static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue); | ||
160 | static int smctr_issue_test_internal_rom_cmd(struct net_device *dev); | ||
161 | static int smctr_issue_test_hic_cmd(struct net_device *dev); | ||
162 | static int smctr_issue_test_mac_reg_cmd(struct net_device *dev); | ||
163 | static int smctr_issue_trc_loopback_cmd(struct net_device *dev); | ||
164 | static int smctr_issue_tri_loopback_cmd(struct net_device *dev); | ||
165 | static int smctr_issue_write_byte_cmd(struct net_device *dev, | ||
166 | short aword_cnt, void *byte); | ||
167 | static int smctr_issue_write_word_cmd(struct net_device *dev, | ||
168 | short aword_cnt, void *word); | ||
169 | |||
170 | /* J */ | ||
171 | static int smctr_join_complete_state(struct net_device *dev); | ||
172 | |||
173 | /* L */ | ||
174 | static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev); | ||
175 | static int smctr_load_firmware(struct net_device *dev); | ||
176 | static int smctr_load_node_addr(struct net_device *dev); | ||
177 | static int smctr_lobe_media_test(struct net_device *dev); | ||
178 | static int smctr_lobe_media_test_cmd(struct net_device *dev); | ||
179 | static int smctr_lobe_media_test_state(struct net_device *dev); | ||
180 | |||
181 | /* M */ | ||
182 | static int smctr_make_8025_hdr(struct net_device *dev, | ||
183 | MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc); | ||
184 | static int smctr_make_access_pri(struct net_device *dev, | ||
185 | MAC_SUB_VECTOR *tsv); | ||
186 | static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv); | ||
187 | static int smctr_make_auth_funct_class(struct net_device *dev, | ||
188 | MAC_SUB_VECTOR *tsv); | ||
189 | static int smctr_make_corr(struct net_device *dev, | ||
190 | MAC_SUB_VECTOR *tsv, __u16 correlator); | ||
191 | static int smctr_make_funct_addr(struct net_device *dev, | ||
192 | MAC_SUB_VECTOR *tsv); | ||
193 | static int smctr_make_group_addr(struct net_device *dev, | ||
194 | MAC_SUB_VECTOR *tsv); | ||
195 | static int smctr_make_phy_drop_num(struct net_device *dev, | ||
196 | MAC_SUB_VECTOR *tsv); | ||
197 | static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv); | ||
198 | static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv); | ||
199 | static int smctr_make_ring_station_status(struct net_device *dev, | ||
200 | MAC_SUB_VECTOR *tsv); | ||
201 | static int smctr_make_ring_station_version(struct net_device *dev, | ||
202 | MAC_SUB_VECTOR *tsv); | ||
203 | static int smctr_make_tx_status_code(struct net_device *dev, | ||
204 | MAC_SUB_VECTOR *tsv, __u16 tx_fstatus); | ||
205 | static int smctr_make_upstream_neighbor_addr(struct net_device *dev, | ||
206 | MAC_SUB_VECTOR *tsv); | ||
207 | static int smctr_make_wrap_data(struct net_device *dev, | ||
208 | MAC_SUB_VECTOR *tsv); | ||
209 | |||
210 | /* O */ | ||
211 | static int smctr_open(struct net_device *dev); | ||
212 | static int smctr_open_tr(struct net_device *dev); | ||
213 | |||
214 | /* P */ | ||
215 | struct net_device *smctr_probe(int unit); | ||
216 | static int __init smctr_probe1(struct net_device *dev, int ioaddr); | ||
217 | static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, | ||
218 | struct net_device *dev, __u16 rx_status); | ||
219 | |||
220 | /* R */ | ||
221 | static int smctr_ram_memory_test(struct net_device *dev); | ||
222 | static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, | ||
223 | __u16 *correlator); | ||
224 | static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, | ||
225 | __u16 *correlator); | ||
226 | static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf); | ||
227 | static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, | ||
228 | MAC_HEADER *rmf, __u16 *correlator); | ||
229 | static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, | ||
230 | __u16 *correlator); | ||
231 | static int smctr_reset_adapter(struct net_device *dev); | ||
232 | static int smctr_restart_tx_chain(struct net_device *dev, short queue); | ||
233 | static int smctr_ring_status_chg(struct net_device *dev); | ||
234 | static int smctr_rx_frame(struct net_device *dev); | ||
235 | |||
236 | /* S */ | ||
237 | static int smctr_send_dat(struct net_device *dev); | ||
238 | static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev); | ||
239 | static int smctr_send_lobe_media_test(struct net_device *dev); | ||
240 | static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, | ||
241 | __u16 correlator); | ||
242 | static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, | ||
243 | __u16 correlator); | ||
244 | static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, | ||
245 | __u16 correlator); | ||
246 | static int smctr_send_rpt_tx_forward(struct net_device *dev, | ||
247 | MAC_HEADER *rmf, __u16 tx_fstatus); | ||
248 | static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, | ||
249 | __u16 rcode, __u16 correlator); | ||
250 | static int smctr_send_rq_init(struct net_device *dev); | ||
251 | static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, | ||
252 | __u16 *tx_fstatus); | ||
253 | static int smctr_set_auth_access_pri(struct net_device *dev, | ||
254 | MAC_SUB_VECTOR *rsv); | ||
255 | static int smctr_set_auth_funct_class(struct net_device *dev, | ||
256 | MAC_SUB_VECTOR *rsv); | ||
257 | static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, | ||
258 | __u16 *correlator); | ||
259 | static int smctr_set_error_timer_value(struct net_device *dev, | ||
260 | MAC_SUB_VECTOR *rsv); | ||
261 | static int smctr_set_frame_forward(struct net_device *dev, | ||
262 | MAC_SUB_VECTOR *rsv, __u8 dc_sc); | ||
263 | static int smctr_set_local_ring_num(struct net_device *dev, | ||
264 | MAC_SUB_VECTOR *rsv); | ||
265 | static unsigned short smctr_set_ctrl_attention(struct net_device *dev); | ||
266 | static void smctr_set_multicast_list(struct net_device *dev); | ||
267 | static int smctr_set_page(struct net_device *dev, __u8 *buf); | ||
268 | static int smctr_set_phy_drop(struct net_device *dev, | ||
269 | MAC_SUB_VECTOR *rsv); | ||
270 | static int smctr_set_ring_speed(struct net_device *dev); | ||
271 | static int smctr_set_rx_look_ahead(struct net_device *dev); | ||
272 | static int smctr_set_trc_reset(int ioaddr); | ||
273 | static int smctr_setup_single_cmd(struct net_device *dev, | ||
274 | __u16 command, __u16 subcommand); | ||
275 | static int smctr_setup_single_cmd_w_data(struct net_device *dev, | ||
276 | __u16 command, __u16 subcommand); | ||
277 | static char *smctr_malloc(struct net_device *dev, __u16 size); | ||
278 | static int smctr_status_chg(struct net_device *dev); | ||
279 | |||
280 | /* T */ | ||
281 | static void smctr_timeout(struct net_device *dev); | ||
282 | static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, | ||
283 | __u16 queue); | ||
284 | static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue); | ||
285 | static unsigned short smctr_tx_move_frame(struct net_device *dev, | ||
286 | struct sk_buff *skb, __u8 *pbuff, unsigned int bytes); | ||
287 | |||
288 | /* U */ | ||
289 | static int smctr_update_err_stats(struct net_device *dev); | ||
290 | static int smctr_update_rx_chain(struct net_device *dev, __u16 queue); | ||
291 | static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, | ||
292 | __u16 queue); | ||
293 | |||
294 | /* W */ | ||
295 | static int smctr_wait_cmd(struct net_device *dev); | ||
296 | static int smctr_wait_while_cbusy(struct net_device *dev); | ||
297 | |||
298 | #define TO_256_BYTE_BOUNDRY(X) (((X + 0xff) & 0xff00) - X) | ||
299 | #define TO_PARAGRAPH_BOUNDRY(X) (((X + 0x0f) & 0xfff0) - X) | ||
300 | #define PARAGRAPH_BOUNDRY(X) smctr_malloc(dev, TO_PARAGRAPH_BOUNDRY(X)) | ||
301 | |||
302 | /* Allocate Adapter Shared Memory. | ||
303 | * IMPORTANT NOTE: Any changes to this function MUST be mirrored in the | ||
304 | * function "get_num_rx_bdbs" below!!! | ||
305 | * | ||
306 | * Order of memory allocation: | ||
307 | * | ||
308 | * 0. Initial System Configuration Block Pointer | ||
309 | * 1. System Configuration Block | ||
310 | * 2. System Control Block | ||
311 | * 3. Action Command Block | ||
312 | * 4. Interrupt Status Block | ||
313 | * | ||
314 | * 5. MAC TX FCB'S | ||
315 | * 6. NON-MAC TX FCB'S | ||
316 | * 7. MAC TX BDB'S | ||
317 | * 8. NON-MAC TX BDB'S | ||
318 | * 9. MAC RX FCB'S | ||
319 | * 10. NON-MAC RX FCB'S | ||
320 | * 11. MAC RX BDB'S | ||
321 | * 12. NON-MAC RX BDB'S | ||
322 | * 13. MAC TX Data Buffer( 1, 256 byte buffer) | ||
323 | * 14. MAC RX Data Buffer( 1, 256 byte buffer) | ||
324 | * | ||
325 | * 15. NON-MAC TX Data Buffer | ||
326 | * 16. NON-MAC RX Data Buffer | ||
327 | */ | ||
328 | static int smctr_alloc_shared_memory(struct net_device *dev) | ||
329 | { | ||
330 | struct net_local *tp = netdev_priv(dev); | ||
331 | |||
332 | if(smctr_debug > 10) | ||
333 | printk(KERN_DEBUG "%s: smctr_alloc_shared_memory\n", dev->name); | ||
334 | |||
335 | /* Allocate initial System Control Block pointer. | ||
336 | * This pointer is located in the last page, last offset - 4. | ||
337 | */ | ||
338 | tp->iscpb_ptr = (ISCPBlock *)(tp->ram_access + ((__u32)64 * 0x400) | ||
339 | - (long)ISCP_BLOCK_SIZE); | ||
340 | |||
341 | /* Allocate System Control Blocks. */ | ||
342 | tp->scgb_ptr = (SCGBlock *)smctr_malloc(dev, sizeof(SCGBlock)); | ||
343 | PARAGRAPH_BOUNDRY(tp->sh_mem_used); | ||
344 | |||
345 | tp->sclb_ptr = (SCLBlock *)smctr_malloc(dev, sizeof(SCLBlock)); | ||
346 | PARAGRAPH_BOUNDRY(tp->sh_mem_used); | ||
347 | |||
348 | tp->acb_head = (ACBlock *)smctr_malloc(dev, | ||
349 | sizeof(ACBlock)*tp->num_acbs); | ||
350 | PARAGRAPH_BOUNDRY(tp->sh_mem_used); | ||
351 | |||
352 | tp->isb_ptr = (ISBlock *)smctr_malloc(dev, sizeof(ISBlock)); | ||
353 | PARAGRAPH_BOUNDRY(tp->sh_mem_used); | ||
354 | |||
355 | tp->misc_command_data = (__u16 *)smctr_malloc(dev, MISC_DATA_SIZE); | ||
356 | PARAGRAPH_BOUNDRY(tp->sh_mem_used); | ||
357 | |||
358 | /* Allocate transmit FCBs. */ | ||
359 | tp->tx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, | ||
360 | sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]); | ||
361 | |||
362 | tp->tx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, | ||
363 | sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]); | ||
364 | |||
365 | tp->tx_fcb_head[BUG_QUEUE] = (FCBlock *)smctr_malloc(dev, | ||
366 | sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]); | ||
367 | |||
368 | /* Allocate transmit BDBs. */ | ||
369 | tp->tx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, | ||
370 | sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]); | ||
371 | |||
372 | tp->tx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, | ||
373 | sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]); | ||
374 | |||
375 | tp->tx_bdb_head[BUG_QUEUE] = (BDBlock *)smctr_malloc(dev, | ||
376 | sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]); | ||
377 | |||
378 | /* Allocate receive FCBs. */ | ||
379 | tp->rx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, | ||
380 | sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]); | ||
381 | |||
382 | tp->rx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, | ||
383 | sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]); | ||
384 | |||
385 | /* Allocate receive BDBs. */ | ||
386 | tp->rx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, | ||
387 | sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]); | ||
388 | |||
389 | tp->rx_bdb_end[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); | ||
390 | |||
391 | tp->rx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, | ||
392 | sizeof(BDBlock) * tp->num_rx_bdbs[NON_MAC_QUEUE]); | ||
393 | |||
394 | tp->rx_bdb_end[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); | ||
395 | |||
396 | /* Allocate MAC transmit buffers. | ||
397 | * MAC Tx Buffers doen't have to be on an ODD Boundry. | ||
398 | */ | ||
399 | tp->tx_buff_head[MAC_QUEUE] | ||
400 | = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[MAC_QUEUE]); | ||
401 | tp->tx_buff_curr[MAC_QUEUE] = tp->tx_buff_head[MAC_QUEUE]; | ||
402 | tp->tx_buff_end [MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); | ||
403 | |||
404 | /* Allocate BUG transmit buffers. */ | ||
405 | tp->tx_buff_head[BUG_QUEUE] | ||
406 | = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[BUG_QUEUE]); | ||
407 | tp->tx_buff_curr[BUG_QUEUE] = tp->tx_buff_head[BUG_QUEUE]; | ||
408 | tp->tx_buff_end[BUG_QUEUE] = (__u16 *)smctr_malloc(dev, 0); | ||
409 | |||
410 | /* Allocate MAC receive data buffers. | ||
411 | * MAC Rx buffer doesn't have to be on a 256 byte boundary. | ||
412 | */ | ||
413 | tp->rx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, | ||
414 | RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]); | ||
415 | tp->rx_buff_end[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); | ||
416 | |||
417 | /* Allocate Non-MAC transmit buffers. | ||
418 | * ?? For maximum Netware performance, put Tx Buffers on | ||
419 | * ODD Boundry and then restore malloc to Even Boundrys. | ||
420 | */ | ||
421 | smctr_malloc(dev, 1L); | ||
422 | tp->tx_buff_head[NON_MAC_QUEUE] | ||
423 | = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[NON_MAC_QUEUE]); | ||
424 | tp->tx_buff_curr[NON_MAC_QUEUE] = tp->tx_buff_head[NON_MAC_QUEUE]; | ||
425 | tp->tx_buff_end [NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); | ||
426 | smctr_malloc(dev, 1L); | ||
427 | |||
428 | /* Allocate Non-MAC receive data buffers. | ||
429 | * To guarantee a minimum of 256 contigous memory to | ||
430 | * UM_Receive_Packet's lookahead pointer, before a page | ||
431 | * change or ring end is encountered, place each rx buffer on | ||
432 | * a 256 byte boundary. | ||
433 | */ | ||
434 | smctr_malloc(dev, TO_256_BYTE_BOUNDRY(tp->sh_mem_used)); | ||
435 | tp->rx_buff_head[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, | ||
436 | RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]); | ||
437 | tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); | ||
438 | |||
439 | return (0); | ||
440 | } | ||
441 | |||
442 | /* Enter Bypass state. */ | ||
443 | static int smctr_bypass_state(struct net_device *dev) | ||
444 | { | ||
445 | int err; | ||
446 | |||
447 | if(smctr_debug > 10) | ||
448 | printk(KERN_DEBUG "%s: smctr_bypass_state\n", dev->name); | ||
449 | |||
450 | err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE); | ||
451 | |||
452 | return (err); | ||
453 | } | ||
454 | |||
455 | static int smctr_checksum_firmware(struct net_device *dev) | ||
456 | { | ||
457 | struct net_local *tp = netdev_priv(dev); | ||
458 | __u16 i, checksum = 0; | ||
459 | |||
460 | if(smctr_debug > 10) | ||
461 | printk(KERN_DEBUG "%s: smctr_checksum_firmware\n", dev->name); | ||
462 | |||
463 | smctr_enable_adapter_ctrl_store(dev); | ||
464 | |||
465 | for(i = 0; i < CS_RAM_SIZE; i += 2) | ||
466 | checksum += *((__u16 *)(tp->ram_access + i)); | ||
467 | |||
468 | tp->microcode_version = *(__u16 *)(tp->ram_access | ||
469 | + CS_RAM_VERSION_OFFSET); | ||
470 | tp->microcode_version >>= 8; | ||
471 | |||
472 | smctr_disable_adapter_ctrl_store(dev); | ||
473 | |||
474 | if(checksum) | ||
475 | return (checksum); | ||
476 | |||
477 | return (0); | ||
478 | } | ||
479 | |||
480 | static int __init smctr_chk_mca(struct net_device *dev) | ||
481 | { | ||
482 | #ifdef CONFIG_MCA_LEGACY | ||
483 | struct net_local *tp = netdev_priv(dev); | ||
484 | int current_slot; | ||
485 | __u8 r1, r2, r3, r4, r5; | ||
486 | |||
487 | current_slot = mca_find_unused_adapter(smctr_posid, 0); | ||
488 | if(current_slot == MCA_NOTFOUND) | ||
489 | return (-ENODEV); | ||
490 | |||
491 | mca_set_adapter_name(current_slot, smctr_name); | ||
492 | mca_mark_as_used(current_slot); | ||
493 | tp->slot_num = current_slot; | ||
494 | |||
495 | r1 = mca_read_stored_pos(tp->slot_num, 2); | ||
496 | r2 = mca_read_stored_pos(tp->slot_num, 3); | ||
497 | |||
498 | if(tp->slot_num) | ||
499 | outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num - 1) | CNFG_SLOT_ENABLE_BIT)); | ||
500 | else | ||
501 | outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num) | CNFG_SLOT_ENABLE_BIT)); | ||
502 | |||
503 | r1 = inb(CNFG_POS_REG1); | ||
504 | r2 = inb(CNFG_POS_REG0); | ||
505 | |||
506 | tp->bic_type = BIC_594_CHIP; | ||
507 | |||
508 | /* IO */ | ||
509 | r2 = mca_read_stored_pos(tp->slot_num, 2); | ||
510 | r2 &= 0xF0; | ||
511 | dev->base_addr = ((__u16)r2 << 8) + (__u16)0x800; | ||
512 | request_region(dev->base_addr, SMCTR_IO_EXTENT, smctr_name); | ||
513 | |||
514 | /* IRQ */ | ||
515 | r5 = mca_read_stored_pos(tp->slot_num, 5); | ||
516 | r5 &= 0xC; | ||
517 | switch(r5) | ||
518 | { | ||
519 | case 0: | ||
520 | dev->irq = 3; | ||
521 | break; | ||
522 | |||
523 | case 0x4: | ||
524 | dev->irq = 4; | ||
525 | break; | ||
526 | |||
527 | case 0x8: | ||
528 | dev->irq = 10; | ||
529 | break; | ||
530 | |||
531 | default: | ||
532 | dev->irq = 15; | ||
533 | break; | ||
534 | } | ||
535 | if (request_irq(dev->irq, smctr_interrupt, SA_SHIRQ, smctr_name, dev)) { | ||
536 | release_region(dev->base_addr, SMCTR_IO_EXTENT); | ||
537 | return -ENODEV; | ||
538 | } | ||
539 | |||
540 | /* Get RAM base */ | ||
541 | r3 = mca_read_stored_pos(tp->slot_num, 3); | ||
542 | tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0C0000; | ||
543 | if (r3 & 0x8) | ||
544 | tp->ram_base += 0x010000; | ||
545 | if (r3 & 0x80) | ||
546 | tp->ram_base += 0xF00000; | ||
547 | |||
548 | /* Get Ram Size */ | ||
549 | r3 &= 0x30; | ||
550 | r3 >>= 4; | ||
551 | |||
552 | tp->ram_usable = (__u16)CNFG_SIZE_8KB << r3; | ||
553 | tp->ram_size = (__u16)CNFG_SIZE_64KB; | ||
554 | tp->board_id |= TOKEN_MEDIA; | ||
555 | |||
556 | r4 = mca_read_stored_pos(tp->slot_num, 4); | ||
557 | tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0x0C0000; | ||
558 | if (r4 & 0x8) | ||
559 | tp->rom_base += 0x010000; | ||
560 | |||
561 | /* Get ROM size. */ | ||
562 | r4 >>= 4; | ||
563 | switch (r4) { | ||
564 | case 0: | ||
565 | tp->rom_size = CNFG_SIZE_8KB; | ||
566 | break; | ||
567 | case 1: | ||
568 | tp->rom_size = CNFG_SIZE_16KB; | ||
569 | break; | ||
570 | case 2: | ||
571 | tp->rom_size = CNFG_SIZE_32KB; | ||
572 | break; | ||
573 | default: | ||
574 | tp->rom_size = ROM_DISABLE; | ||
575 | } | ||
576 | |||
577 | /* Get Media Type. */ | ||
578 | r5 = mca_read_stored_pos(tp->slot_num, 5); | ||
579 | r5 &= CNFG_MEDIA_TYPE_MASK; | ||
580 | switch(r5) | ||
581 | { | ||
582 | case (0): | ||
583 | tp->media_type = MEDIA_STP_4; | ||
584 | break; | ||
585 | |||
586 | case (1): | ||
587 | tp->media_type = MEDIA_STP_16; | ||
588 | break; | ||
589 | |||
590 | case (3): | ||
591 | tp->media_type = MEDIA_UTP_16; | ||
592 | break; | ||
593 | |||
594 | default: | ||
595 | tp->media_type = MEDIA_UTP_4; | ||
596 | break; | ||
597 | } | ||
598 | tp->media_menu = 14; | ||
599 | |||
600 | r2 = mca_read_stored_pos(tp->slot_num, 2); | ||
601 | if(!(r2 & 0x02)) | ||
602 | tp->mode_bits |= EARLY_TOKEN_REL; | ||
603 | |||
604 | /* Disable slot */ | ||
605 | outb(CNFG_POS_CONTROL_REG, 0); | ||
606 | |||
607 | tp->board_id = smctr_get_boardid(dev, 1); | ||
608 | switch(tp->board_id & 0xffff) | ||
609 | { | ||
610 | case WD8115TA: | ||
611 | smctr_model = "8115T/A"; | ||
612 | break; | ||
613 | |||
614 | case WD8115T: | ||
615 | if(tp->extra_info & CHIP_REV_MASK) | ||
616 | smctr_model = "8115T rev XE"; | ||
617 | else | ||
618 | smctr_model = "8115T rev XD"; | ||
619 | break; | ||
620 | |||
621 | default: | ||
622 | smctr_model = "Unknown"; | ||
623 | break; | ||
624 | } | ||
625 | |||
626 | return (0); | ||
627 | #else | ||
628 | return (-1); | ||
629 | #endif /* CONFIG_MCA_LEGACY */ | ||
630 | } | ||
631 | |||
632 | static int smctr_chg_rx_mask(struct net_device *dev) | ||
633 | { | ||
634 | struct net_local *tp = netdev_priv(dev); | ||
635 | int err = 0; | ||
636 | |||
637 | if(smctr_debug > 10) | ||
638 | printk(KERN_DEBUG "%s: smctr_chg_rx_mask\n", dev->name); | ||
639 | |||
640 | smctr_enable_16bit(dev); | ||
641 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
642 | |||
643 | if(tp->mode_bits & LOOPING_MODE_MASK) | ||
644 | tp->config_word0 |= RX_OWN_BIT; | ||
645 | else | ||
646 | tp->config_word0 &= ~RX_OWN_BIT; | ||
647 | |||
648 | if(tp->receive_mask & PROMISCUOUS_MODE) | ||
649 | tp->config_word0 |= PROMISCUOUS_BIT; | ||
650 | else | ||
651 | tp->config_word0 &= ~PROMISCUOUS_BIT; | ||
652 | |||
653 | if(tp->receive_mask & ACCEPT_ERR_PACKETS) | ||
654 | tp->config_word0 |= SAVBAD_BIT; | ||
655 | else | ||
656 | tp->config_word0 &= ~SAVBAD_BIT; | ||
657 | |||
658 | if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) | ||
659 | tp->config_word0 |= RXATMAC; | ||
660 | else | ||
661 | tp->config_word0 &= ~RXATMAC; | ||
662 | |||
663 | if(tp->receive_mask & ACCEPT_MULTI_PROM) | ||
664 | tp->config_word1 |= MULTICAST_ADDRESS_BIT; | ||
665 | else | ||
666 | tp->config_word1 &= ~MULTICAST_ADDRESS_BIT; | ||
667 | |||
668 | if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING) | ||
669 | tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS; | ||
670 | else | ||
671 | { | ||
672 | if(tp->receive_mask & ACCEPT_SOURCE_ROUTING) | ||
673 | tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT; | ||
674 | else | ||
675 | tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS; | ||
676 | } | ||
677 | |||
678 | if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0, | ||
679 | &tp->config_word0))) | ||
680 | { | ||
681 | return (err); | ||
682 | } | ||
683 | |||
684 | if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1, | ||
685 | &tp->config_word1))) | ||
686 | { | ||
687 | return (err); | ||
688 | } | ||
689 | |||
690 | smctr_disable_16bit(dev); | ||
691 | |||
692 | return (0); | ||
693 | } | ||
694 | |||
695 | static int smctr_clear_int(struct net_device *dev) | ||
696 | { | ||
697 | struct net_local *tp = netdev_priv(dev); | ||
698 | |||
699 | outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR); | ||
700 | |||
701 | return (0); | ||
702 | } | ||
703 | |||
704 | static int smctr_clear_trc_reset(int ioaddr) | ||
705 | { | ||
706 | __u8 r; | ||
707 | |||
708 | r = inb(ioaddr + MSR); | ||
709 | outb(~MSR_RST & r, ioaddr + MSR); | ||
710 | |||
711 | return (0); | ||
712 | } | ||
713 | |||
714 | /* | ||
715 | * The inverse routine to smctr_open(). | ||
716 | */ | ||
717 | static int smctr_close(struct net_device *dev) | ||
718 | { | ||
719 | struct net_local *tp = netdev_priv(dev); | ||
720 | struct sk_buff *skb; | ||
721 | int err; | ||
722 | |||
723 | netif_stop_queue(dev); | ||
724 | |||
725 | tp->cleanup = 1; | ||
726 | |||
727 | /* Check to see if adapter is already in a closed state. */ | ||
728 | if(tp->status != OPEN) | ||
729 | return (0); | ||
730 | |||
731 | smctr_enable_16bit(dev); | ||
732 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
733 | |||
734 | if((err = smctr_issue_remove_cmd(dev))) | ||
735 | { | ||
736 | smctr_disable_16bit(dev); | ||
737 | return (err); | ||
738 | } | ||
739 | |||
740 | for(;;) | ||
741 | { | ||
742 | skb = skb_dequeue(&tp->SendSkbQueue); | ||
743 | if(skb == NULL) | ||
744 | break; | ||
745 | tp->QueueSkb++; | ||
746 | dev_kfree_skb(skb); | ||
747 | } | ||
748 | |||
749 | |||
750 | return (0); | ||
751 | } | ||
752 | |||
753 | static int smctr_decode_firmware(struct net_device *dev) | ||
754 | { | ||
755 | struct net_local *tp = netdev_priv(dev); | ||
756 | short bit = 0x80, shift = 12; | ||
757 | DECODE_TREE_NODE *tree; | ||
758 | short branch, tsize; | ||
759 | __u16 buff = 0; | ||
760 | long weight; | ||
761 | __u8 *ucode; | ||
762 | __u16 *mem; | ||
763 | |||
764 | if(smctr_debug > 10) | ||
765 | printk(KERN_DEBUG "%s: smctr_decode_firmware\n", dev->name); | ||
766 | |||
767 | weight = *(long *)(tp->ptr_ucode + WEIGHT_OFFSET); | ||
768 | tsize = *(__u8 *)(tp->ptr_ucode + TREE_SIZE_OFFSET); | ||
769 | tree = (DECODE_TREE_NODE *)(tp->ptr_ucode + TREE_OFFSET); | ||
770 | ucode = (__u8 *)(tp->ptr_ucode + TREE_OFFSET | ||
771 | + (tsize * sizeof(DECODE_TREE_NODE))); | ||
772 | mem = (__u16 *)(tp->ram_access); | ||
773 | |||
774 | while(weight) | ||
775 | { | ||
776 | branch = ROOT; | ||
777 | while((tree + branch)->tag != LEAF && weight) | ||
778 | { | ||
779 | branch = *ucode & bit ? (tree + branch)->llink | ||
780 | : (tree + branch)->rlink; | ||
781 | |||
782 | bit >>= 1; | ||
783 | weight--; | ||
784 | |||
785 | if(bit == 0) | ||
786 | { | ||
787 | bit = 0x80; | ||
788 | ucode++; | ||
789 | } | ||
790 | } | ||
791 | |||
792 | buff |= (tree + branch)->info << shift; | ||
793 | shift -= 4; | ||
794 | |||
795 | if(shift < 0) | ||
796 | { | ||
797 | *(mem++) = SWAP_BYTES(buff); | ||
798 | buff = 0; | ||
799 | shift = 12; | ||
800 | } | ||
801 | } | ||
802 | |||
803 | /* The following assumes the Control Store Memory has | ||
804 | * been initialized to zero. If the last partial word | ||
805 | * is zero, it will not be written. | ||
806 | */ | ||
807 | if(buff) | ||
808 | *(mem++) = SWAP_BYTES(buff); | ||
809 | |||
810 | return (0); | ||
811 | } | ||
812 | |||
813 | static int smctr_disable_16bit(struct net_device *dev) | ||
814 | { | ||
815 | return (0); | ||
816 | } | ||
817 | |||
818 | /* | ||
819 | * On Exit, Adapter is: | ||
820 | * 1. TRC is in a reset state and un-initialized. | ||
821 | * 2. Adapter memory is enabled. | ||
822 | * 3. Control Store memory is out of context (-WCSS is 1). | ||
823 | */ | ||
824 | static int smctr_disable_adapter_ctrl_store(struct net_device *dev) | ||
825 | { | ||
826 | struct net_local *tp = netdev_priv(dev); | ||
827 | int ioaddr = dev->base_addr; | ||
828 | |||
829 | if(smctr_debug > 10) | ||
830 | printk(KERN_DEBUG "%s: smctr_disable_adapter_ctrl_store\n", dev->name); | ||
831 | |||
832 | tp->trc_mask |= CSR_WCSS; | ||
833 | outb(tp->trc_mask, ioaddr + CSR); | ||
834 | |||
835 | return (0); | ||
836 | } | ||
837 | |||
838 | static int smctr_disable_bic_int(struct net_device *dev) | ||
839 | { | ||
840 | struct net_local *tp = netdev_priv(dev); | ||
841 | int ioaddr = dev->base_addr; | ||
842 | |||
843 | tp->trc_mask = CSR_MSK_ALL | CSR_MSKCBUSY | ||
844 | | CSR_MSKTINT | CSR_WCSS; | ||
845 | outb(tp->trc_mask, ioaddr + CSR); | ||
846 | |||
847 | return (0); | ||
848 | } | ||
849 | |||
850 | static int smctr_enable_16bit(struct net_device *dev) | ||
851 | { | ||
852 | struct net_local *tp = netdev_priv(dev); | ||
853 | __u8 r; | ||
854 | |||
855 | if(tp->adapter_bus == BUS_ISA16_TYPE) | ||
856 | { | ||
857 | r = inb(dev->base_addr + LAAR); | ||
858 | outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR); | ||
859 | } | ||
860 | |||
861 | return (0); | ||
862 | } | ||
863 | |||
864 | /* | ||
865 | * To enable the adapter control store memory: | ||
866 | * 1. Adapter must be in a RESET state. | ||
867 | * 2. Adapter memory must be enabled. | ||
868 | * 3. Control Store Memory is in context (-WCSS is 0). | ||
869 | */ | ||
870 | static int smctr_enable_adapter_ctrl_store(struct net_device *dev) | ||
871 | { | ||
872 | struct net_local *tp = netdev_priv(dev); | ||
873 | int ioaddr = dev->base_addr; | ||
874 | |||
875 | if(smctr_debug > 10) | ||
876 | printk(KERN_DEBUG "%s: smctr_enable_adapter_ctrl_store\n", dev->name); | ||
877 | |||
878 | smctr_set_trc_reset(ioaddr); | ||
879 | smctr_enable_adapter_ram(dev); | ||
880 | |||
881 | tp->trc_mask &= ~CSR_WCSS; | ||
882 | outb(tp->trc_mask, ioaddr + CSR); | ||
883 | |||
884 | return (0); | ||
885 | } | ||
886 | |||
887 | static int smctr_enable_adapter_ram(struct net_device *dev) | ||
888 | { | ||
889 | int ioaddr = dev->base_addr; | ||
890 | __u8 r; | ||
891 | |||
892 | if(smctr_debug > 10) | ||
893 | printk(KERN_DEBUG "%s: smctr_enable_adapter_ram\n", dev->name); | ||
894 | |||
895 | r = inb(ioaddr + MSR); | ||
896 | outb(MSR_MEMB | r, ioaddr + MSR); | ||
897 | |||
898 | return (0); | ||
899 | } | ||
900 | |||
901 | static int smctr_enable_bic_int(struct net_device *dev) | ||
902 | { | ||
903 | struct net_local *tp = netdev_priv(dev); | ||
904 | int ioaddr = dev->base_addr; | ||
905 | __u8 r; | ||
906 | |||
907 | switch(tp->bic_type) | ||
908 | { | ||
909 | case (BIC_584_CHIP): | ||
910 | tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS; | ||
911 | outb(tp->trc_mask, ioaddr + CSR); | ||
912 | r = inb(ioaddr + IRR); | ||
913 | outb(r | IRR_IEN, ioaddr + IRR); | ||
914 | break; | ||
915 | |||
916 | case (BIC_594_CHIP): | ||
917 | tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS; | ||
918 | outb(tp->trc_mask, ioaddr + CSR); | ||
919 | r = inb(ioaddr + IMCCR); | ||
920 | outb(r | IMCCR_EIL, ioaddr + IMCCR); | ||
921 | break; | ||
922 | } | ||
923 | |||
924 | return (0); | ||
925 | } | ||
926 | |||
927 | static int __init smctr_chk_isa(struct net_device *dev) | ||
928 | { | ||
929 | struct net_local *tp = netdev_priv(dev); | ||
930 | int ioaddr = dev->base_addr; | ||
931 | __u8 r1, r2, b, chksum = 0; | ||
932 | __u16 r; | ||
933 | int i; | ||
934 | int err = -ENODEV; | ||
935 | |||
936 | if(smctr_debug > 10) | ||
937 | printk(KERN_DEBUG "%s: smctr_chk_isa %#4x\n", dev->name, ioaddr); | ||
938 | |||
939 | if((ioaddr & 0x1F) != 0) | ||
940 | goto out; | ||
941 | |||
942 | /* Grab the region so that no one else tries to probe our ioports. */ | ||
943 | if (!request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name)) { | ||
944 | err = -EBUSY; | ||
945 | goto out; | ||
946 | } | ||
947 | |||
948 | /* Checksum SMC node address */ | ||
949 | for(i = 0; i < 8; i++) | ||
950 | { | ||
951 | b = inb(ioaddr + LAR0 + i); | ||
952 | chksum += b; | ||
953 | } | ||
954 | |||
955 | if (chksum != NODE_ADDR_CKSUM) | ||
956 | goto out2; | ||
957 | |||
958 | b = inb(ioaddr + BDID); | ||
959 | if(b != BRD_ID_8115T) | ||
960 | { | ||
961 | printk(KERN_ERR "%s: The adapter found is not supported\n", dev->name); | ||
962 | goto out2; | ||
963 | } | ||
964 | |||
965 | /* Check for 8115T Board ID */ | ||
966 | r2 = 0; | ||
967 | for(r = 0; r < 8; r++) | ||
968 | { | ||
969 | r1 = inb(ioaddr + 0x8 + r); | ||
970 | r2 += r1; | ||
971 | } | ||
972 | |||
973 | /* value of RegF adds up the sum to 0xFF */ | ||
974 | if((r2 != 0xFF) && (r2 != 0xEE)) | ||
975 | goto out2; | ||
976 | |||
977 | /* Get adapter ID */ | ||
978 | tp->board_id = smctr_get_boardid(dev, 0); | ||
979 | switch(tp->board_id & 0xffff) | ||
980 | { | ||
981 | case WD8115TA: | ||
982 | smctr_model = "8115T/A"; | ||
983 | break; | ||
984 | |||
985 | case WD8115T: | ||
986 | if(tp->extra_info & CHIP_REV_MASK) | ||
987 | smctr_model = "8115T rev XE"; | ||
988 | else | ||
989 | smctr_model = "8115T rev XD"; | ||
990 | break; | ||
991 | |||
992 | default: | ||
993 | smctr_model = "Unknown"; | ||
994 | break; | ||
995 | } | ||
996 | |||
997 | /* Store BIC type. */ | ||
998 | tp->bic_type = BIC_584_CHIP; | ||
999 | tp->nic_type = NIC_825_CHIP; | ||
1000 | |||
1001 | /* Copy Ram Size */ | ||
1002 | tp->ram_usable = CNFG_SIZE_16KB; | ||
1003 | tp->ram_size = CNFG_SIZE_64KB; | ||
1004 | |||
1005 | /* Get 58x Ram Base */ | ||
1006 | r1 = inb(ioaddr); | ||
1007 | r1 &= 0x3F; | ||
1008 | |||
1009 | r2 = inb(ioaddr + CNFG_LAAR_584); | ||
1010 | r2 &= CNFG_LAAR_MASK; | ||
1011 | r2 <<= 3; | ||
1012 | r2 |= ((r1 & 0x38) >> 3); | ||
1013 | |||
1014 | tp->ram_base = ((__u32)r2 << 16) + (((__u32)(r1 & 0x7)) << 13); | ||
1015 | |||
1016 | /* Get 584 Irq */ | ||
1017 | r1 = 0; | ||
1018 | r1 = inb(ioaddr + CNFG_ICR_583); | ||
1019 | r1 &= CNFG_ICR_IR2_584; | ||
1020 | |||
1021 | r2 = inb(ioaddr + CNFG_IRR_583); | ||
1022 | r2 &= CNFG_IRR_IRQS; /* 0x60 */ | ||
1023 | r2 >>= 5; | ||
1024 | |||
1025 | switch(r2) | ||
1026 | { | ||
1027 | case 0: | ||
1028 | if(r1 == 0) | ||
1029 | dev->irq = 2; | ||
1030 | else | ||
1031 | dev->irq = 10; | ||
1032 | break; | ||
1033 | |||
1034 | case 1: | ||
1035 | if(r1 == 0) | ||
1036 | dev->irq = 3; | ||
1037 | else | ||
1038 | dev->irq = 11; | ||
1039 | break; | ||
1040 | |||
1041 | case 2: | ||
1042 | if(r1 == 0) | ||
1043 | { | ||
1044 | if(tp->extra_info & ALTERNATE_IRQ_BIT) | ||
1045 | dev->irq = 5; | ||
1046 | else | ||
1047 | dev->irq = 4; | ||
1048 | } | ||
1049 | else | ||
1050 | dev->irq = 15; | ||
1051 | break; | ||
1052 | |||
1053 | case 3: | ||
1054 | if(r1 == 0) | ||
1055 | dev->irq = 7; | ||
1056 | else | ||
1057 | dev->irq = 4; | ||
1058 | break; | ||
1059 | |||
1060 | default: | ||
1061 | printk(KERN_ERR "%s: No IRQ found aborting\n", dev->name); | ||
1062 | goto out2; | ||
1063 | } | ||
1064 | |||
1065 | if (request_irq(dev->irq, smctr_interrupt, SA_SHIRQ, smctr_name, dev)) | ||
1066 | goto out2; | ||
1067 | |||
1068 | /* Get 58x Rom Base */ | ||
1069 | r1 = inb(ioaddr + CNFG_BIO_583); | ||
1070 | r1 &= 0x3E; | ||
1071 | r1 |= 0x40; | ||
1072 | |||
1073 | tp->rom_base = (__u32)r1 << 13; | ||
1074 | |||
1075 | /* Get 58x Rom Size */ | ||
1076 | r1 = inb(ioaddr + CNFG_BIO_583); | ||
1077 | r1 &= 0xC0; | ||
1078 | if(r1 == 0) | ||
1079 | tp->rom_size = ROM_DISABLE; | ||
1080 | else | ||
1081 | { | ||
1082 | r1 >>= 6; | ||
1083 | tp->rom_size = (__u16)CNFG_SIZE_8KB << r1; | ||
1084 | } | ||
1085 | |||
1086 | /* Get 58x Boot Status */ | ||
1087 | r1 = inb(ioaddr + CNFG_GP2); | ||
1088 | |||
1089 | tp->mode_bits &= (~BOOT_STATUS_MASK); | ||
1090 | |||
1091 | if(r1 & CNFG_GP2_BOOT_NIBBLE) | ||
1092 | tp->mode_bits |= BOOT_TYPE_1; | ||
1093 | |||
1094 | /* Get 58x Zero Wait State */ | ||
1095 | tp->mode_bits &= (~ZERO_WAIT_STATE_MASK); | ||
1096 | |||
1097 | r1 = inb(ioaddr + CNFG_IRR_583); | ||
1098 | |||
1099 | if(r1 & CNFG_IRR_ZWS) | ||
1100 | tp->mode_bits |= ZERO_WAIT_STATE_8_BIT; | ||
1101 | |||
1102 | if(tp->board_id & BOARD_16BIT) | ||
1103 | { | ||
1104 | r1 = inb(ioaddr + CNFG_LAAR_584); | ||
1105 | |||
1106 | if(r1 & CNFG_LAAR_ZWS) | ||
1107 | tp->mode_bits |= ZERO_WAIT_STATE_16_BIT; | ||
1108 | } | ||
1109 | |||
1110 | /* Get 584 Media Menu */ | ||
1111 | tp->media_menu = 14; | ||
1112 | r1 = inb(ioaddr + CNFG_IRR_583); | ||
1113 | |||
1114 | tp->mode_bits &= 0xf8ff; /* (~CNFG_INTERFACE_TYPE_MASK) */ | ||
1115 | if((tp->board_id & TOKEN_MEDIA) == TOKEN_MEDIA) | ||
1116 | { | ||
1117 | /* Get Advanced Features */ | ||
1118 | if(((r1 & 0x6) >> 1) == 0x3) | ||
1119 | tp->media_type |= MEDIA_UTP_16; | ||
1120 | else | ||
1121 | { | ||
1122 | if(((r1 & 0x6) >> 1) == 0x2) | ||
1123 | tp->media_type |= MEDIA_STP_16; | ||
1124 | else | ||
1125 | { | ||
1126 | if(((r1 & 0x6) >> 1) == 0x1) | ||
1127 | tp->media_type |= MEDIA_UTP_4; | ||
1128 | |||
1129 | else | ||
1130 | tp->media_type |= MEDIA_STP_4; | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | r1 = inb(ioaddr + CNFG_GP2); | ||
1135 | if(!(r1 & 0x2) ) /* GP2_ETRD */ | ||
1136 | tp->mode_bits |= EARLY_TOKEN_REL; | ||
1137 | |||
1138 | /* see if the chip is corrupted | ||
1139 | if(smctr_read_584_chksum(ioaddr)) | ||
1140 | { | ||
1141 | printk(KERN_ERR "%s: EEPROM Checksum Failure\n", dev->name); | ||
1142 | free_irq(dev->irq, dev); | ||
1143 | goto out2; | ||
1144 | } | ||
1145 | */ | ||
1146 | } | ||
1147 | |||
1148 | return (0); | ||
1149 | |||
1150 | out2: | ||
1151 | release_region(ioaddr, SMCTR_IO_EXTENT); | ||
1152 | out: | ||
1153 | return err; | ||
1154 | } | ||
1155 | |||
1156 | static int __init smctr_get_boardid(struct net_device *dev, int mca) | ||
1157 | { | ||
1158 | struct net_local *tp = netdev_priv(dev); | ||
1159 | int ioaddr = dev->base_addr; | ||
1160 | __u8 r, r1, IdByte; | ||
1161 | __u16 BoardIdMask; | ||
1162 | |||
1163 | tp->board_id = BoardIdMask = 0; | ||
1164 | |||
1165 | if(mca) | ||
1166 | { | ||
1167 | BoardIdMask |= (MICROCHANNEL+INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); | ||
1168 | tp->extra_info |= (INTERFACE_594_CHIP+RAM_SIZE_64K+NIC_825_BIT+ALTERNATE_IRQ_BIT+SLOT_16BIT); | ||
1169 | } | ||
1170 | else | ||
1171 | { | ||
1172 | BoardIdMask|=(INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); | ||
1173 | tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K | ||
1174 | + NIC_825_BIT + ALTERNATE_IRQ_BIT); | ||
1175 | } | ||
1176 | |||
1177 | if(!mca) | ||
1178 | { | ||
1179 | r = inb(ioaddr + BID_REG_1); | ||
1180 | r &= 0x0c; | ||
1181 | outb(r, ioaddr + BID_REG_1); | ||
1182 | r = inb(ioaddr + BID_REG_1); | ||
1183 | |||
1184 | if(r & BID_SIXTEEN_BIT_BIT) | ||
1185 | { | ||
1186 | tp->extra_info |= SLOT_16BIT; | ||
1187 | tp->adapter_bus = BUS_ISA16_TYPE; | ||
1188 | } | ||
1189 | else | ||
1190 | tp->adapter_bus = BUS_ISA8_TYPE; | ||
1191 | } | ||
1192 | else | ||
1193 | tp->adapter_bus = BUS_MCA_TYPE; | ||
1194 | |||
1195 | /* Get Board Id Byte */ | ||
1196 | IdByte = inb(ioaddr + BID_BOARD_ID_BYTE); | ||
1197 | |||
1198 | /* if Major version > 1.0 then | ||
1199 | * return; | ||
1200 | */ | ||
1201 | if(IdByte & 0xF8) | ||
1202 | return (-1); | ||
1203 | |||
1204 | r1 = inb(ioaddr + BID_REG_1); | ||
1205 | r1 &= BID_ICR_MASK; | ||
1206 | r1 |= BID_OTHER_BIT; | ||
1207 | |||
1208 | outb(r1, ioaddr + BID_REG_1); | ||
1209 | r1 = inb(ioaddr + BID_REG_3); | ||
1210 | |||
1211 | r1 &= BID_EAR_MASK; | ||
1212 | r1 |= BID_ENGR_PAGE; | ||
1213 | |||
1214 | outb(r1, ioaddr + BID_REG_3); | ||
1215 | r1 = inb(ioaddr + BID_REG_1); | ||
1216 | r1 &= BID_ICR_MASK; | ||
1217 | r1 |= (BID_RLA | BID_OTHER_BIT); | ||
1218 | |||
1219 | outb(r1, ioaddr + BID_REG_1); | ||
1220 | |||
1221 | r1 = inb(ioaddr + BID_REG_1); | ||
1222 | while(r1 & BID_RECALL_DONE_MASK) | ||
1223 | r1 = inb(ioaddr + BID_REG_1); | ||
1224 | |||
1225 | r = inb(ioaddr + BID_LAR_0 + BID_REG_6); | ||
1226 | |||
1227 | /* clear chip rev bits */ | ||
1228 | tp->extra_info &= ~CHIP_REV_MASK; | ||
1229 | tp->extra_info |= ((r & BID_EEPROM_CHIP_REV_MASK) << 6); | ||
1230 | |||
1231 | r1 = inb(ioaddr + BID_REG_1); | ||
1232 | r1 &= BID_ICR_MASK; | ||
1233 | r1 |= BID_OTHER_BIT; | ||
1234 | |||
1235 | outb(r1, ioaddr + BID_REG_1); | ||
1236 | r1 = inb(ioaddr + BID_REG_3); | ||
1237 | |||
1238 | r1 &= BID_EAR_MASK; | ||
1239 | r1 |= BID_EA6; | ||
1240 | |||
1241 | outb(r1, ioaddr + BID_REG_3); | ||
1242 | r1 = inb(ioaddr + BID_REG_1); | ||
1243 | |||
1244 | r1 &= BID_ICR_MASK; | ||
1245 | r1 |= BID_RLA; | ||
1246 | |||
1247 | outb(r1, ioaddr + BID_REG_1); | ||
1248 | r1 = inb(ioaddr + BID_REG_1); | ||
1249 | |||
1250 | while(r1 & BID_RECALL_DONE_MASK) | ||
1251 | r1 = inb(ioaddr + BID_REG_1); | ||
1252 | |||
1253 | return (BoardIdMask); | ||
1254 | } | ||
1255 | |||
1256 | static int smctr_get_group_address(struct net_device *dev) | ||
1257 | { | ||
1258 | smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR); | ||
1259 | |||
1260 | return(smctr_wait_cmd(dev)); | ||
1261 | } | ||
1262 | |||
1263 | static int smctr_get_functional_address(struct net_device *dev) | ||
1264 | { | ||
1265 | smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR); | ||
1266 | |||
1267 | return(smctr_wait_cmd(dev)); | ||
1268 | } | ||
1269 | |||
1270 | /* Calculate number of Non-MAC receive BDB's and data buffers. | ||
1271 | * This function must simulate allocateing shared memory exactly | ||
1272 | * as the allocate_shared_memory function above. | ||
1273 | */ | ||
1274 | static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) | ||
1275 | { | ||
1276 | struct net_local *tp = netdev_priv(dev); | ||
1277 | unsigned int mem_used = 0; | ||
1278 | |||
1279 | /* Allocate System Control Blocks. */ | ||
1280 | mem_used += sizeof(SCGBlock); | ||
1281 | |||
1282 | mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); | ||
1283 | mem_used += sizeof(SCLBlock); | ||
1284 | |||
1285 | mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); | ||
1286 | mem_used += sizeof(ACBlock) * tp->num_acbs; | ||
1287 | |||
1288 | mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); | ||
1289 | mem_used += sizeof(ISBlock); | ||
1290 | |||
1291 | mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); | ||
1292 | mem_used += MISC_DATA_SIZE; | ||
1293 | |||
1294 | /* Allocate transmit FCB's. */ | ||
1295 | mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); | ||
1296 | |||
1297 | mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]; | ||
1298 | mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]; | ||
1299 | mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]; | ||
1300 | |||
1301 | /* Allocate transmit BDBs. */ | ||
1302 | mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]; | ||
1303 | mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]; | ||
1304 | mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]; | ||
1305 | |||
1306 | /* Allocate receive FCBs. */ | ||
1307 | mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]; | ||
1308 | mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]; | ||
1309 | |||
1310 | /* Allocate receive BDBs. */ | ||
1311 | mem_used += sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]; | ||
1312 | |||
1313 | /* Allocate MAC transmit buffers. | ||
1314 | * MAC transmit buffers don't have to be on an ODD Boundry. | ||
1315 | */ | ||
1316 | mem_used += tp->tx_buff_size[MAC_QUEUE]; | ||
1317 | |||
1318 | /* Allocate BUG transmit buffers. */ | ||
1319 | mem_used += tp->tx_buff_size[BUG_QUEUE]; | ||
1320 | |||
1321 | /* Allocate MAC receive data buffers. | ||
1322 | * MAC receive buffers don't have to be on a 256 byte boundary. | ||
1323 | */ | ||
1324 | mem_used += RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]; | ||
1325 | |||
1326 | /* Allocate Non-MAC transmit buffers. | ||
1327 | * For maximum Netware performance, put Tx Buffers on | ||
1328 | * ODD Boundry,and then restore malloc to Even Boundrys. | ||
1329 | */ | ||
1330 | mem_used += 1L; | ||
1331 | mem_used += tp->tx_buff_size[NON_MAC_QUEUE]; | ||
1332 | mem_used += 1L; | ||
1333 | |||
1334 | /* CALCULATE NUMBER OF NON-MAC RX BDB'S | ||
1335 | * AND NON-MAC RX DATA BUFFERS | ||
1336 | * | ||
1337 | * Make sure the mem_used offset at this point is the | ||
1338 | * same as in allocate_shared memory or the following | ||
1339 | * boundary adjustment will be incorrect (i.e. not allocating | ||
1340 | * the non-mac receive buffers above cannot change the 256 | ||
1341 | * byte offset). | ||
1342 | * | ||
1343 | * Since this cannot be guaranteed, adding the full 256 bytes | ||
1344 | * to the amount of shared memory used at this point will guaranteed | ||
1345 | * that the rx data buffers do not overflow shared memory. | ||
1346 | */ | ||
1347 | mem_used += 0x100; | ||
1348 | |||
1349 | return((0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock))); | ||
1350 | } | ||
1351 | |||
1352 | static int smctr_get_physical_drop_number(struct net_device *dev) | ||
1353 | { | ||
1354 | smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER); | ||
1355 | |||
1356 | return(smctr_wait_cmd(dev)); | ||
1357 | } | ||
1358 | |||
1359 | static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) | ||
1360 | { | ||
1361 | struct net_local *tp = netdev_priv(dev); | ||
1362 | BDBlock *bdb; | ||
1363 | |||
1364 | bdb = (BDBlock *)((__u32)tp->ram_access | ||
1365 | + (__u32)(tp->rx_fcb_curr[queue]->trc_bdb_ptr)); | ||
1366 | |||
1367 | tp->rx_fcb_curr[queue]->bdb_ptr = bdb; | ||
1368 | |||
1369 | return ((__u8 *)bdb->data_block_ptr); | ||
1370 | } | ||
1371 | |||
1372 | static int smctr_get_station_id(struct net_device *dev) | ||
1373 | { | ||
1374 | smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS); | ||
1375 | |||
1376 | return(smctr_wait_cmd(dev)); | ||
1377 | } | ||
1378 | |||
1379 | /* | ||
1380 | * Get the current statistics. This may be called with the card open | ||
1381 | * or closed. | ||
1382 | */ | ||
1383 | static struct net_device_stats *smctr_get_stats(struct net_device *dev) | ||
1384 | { | ||
1385 | struct net_local *tp = netdev_priv(dev); | ||
1386 | |||
1387 | return ((struct net_device_stats *)&tp->MacStat); | ||
1388 | } | ||
1389 | |||
1390 | static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, | ||
1391 | __u16 bytes_count) | ||
1392 | { | ||
1393 | struct net_local *tp = netdev_priv(dev); | ||
1394 | FCBlock *pFCB; | ||
1395 | BDBlock *pbdb; | ||
1396 | unsigned short alloc_size; | ||
1397 | unsigned short *temp; | ||
1398 | |||
1399 | if(smctr_debug > 20) | ||
1400 | printk(KERN_DEBUG "smctr_get_tx_fcb\n"); | ||
1401 | |||
1402 | /* check if there is enough FCB blocks */ | ||
1403 | if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue]) | ||
1404 | return ((FCBlock *)(-1L)); | ||
1405 | |||
1406 | /* round off the input pkt size to the nearest even number */ | ||
1407 | alloc_size = (bytes_count + 1) & 0xfffe; | ||
1408 | |||
1409 | /* check if enough mem */ | ||
1410 | if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue]) | ||
1411 | return ((FCBlock *)(-1L)); | ||
1412 | |||
1413 | /* check if past the end ; | ||
1414 | * if exactly enough mem to end of ring, alloc from front. | ||
1415 | * this avoids update of curr when curr = end | ||
1416 | */ | ||
1417 | if(((unsigned long)(tp->tx_buff_curr[queue]) + alloc_size) | ||
1418 | >= (unsigned long)(tp->tx_buff_end[queue])) | ||
1419 | { | ||
1420 | /* check if enough memory from ring head */ | ||
1421 | alloc_size = alloc_size + | ||
1422 | (__u16)((__u32)tp->tx_buff_end[queue] | ||
1423 | - (__u32)tp->tx_buff_curr[queue]); | ||
1424 | |||
1425 | if((tp->tx_buff_used[queue] + alloc_size) | ||
1426 | > tp->tx_buff_size[queue]) | ||
1427 | { | ||
1428 | return ((FCBlock *)(-1L)); | ||
1429 | } | ||
1430 | |||
1431 | /* ring wrap */ | ||
1432 | tp->tx_buff_curr[queue] = tp->tx_buff_head[queue]; | ||
1433 | } | ||
1434 | |||
1435 | tp->tx_buff_used[queue] += alloc_size; | ||
1436 | tp->num_tx_fcbs_used[queue]++; | ||
1437 | tp->tx_fcb_curr[queue]->frame_length = bytes_count; | ||
1438 | tp->tx_fcb_curr[queue]->memory_alloc = alloc_size; | ||
1439 | temp = tp->tx_buff_curr[queue]; | ||
1440 | tp->tx_buff_curr[queue] | ||
1441 | = (__u16 *)((__u32)temp + (__u32)((bytes_count + 1) & 0xfffe)); | ||
1442 | |||
1443 | pbdb = tp->tx_fcb_curr[queue]->bdb_ptr; | ||
1444 | pbdb->buffer_length = bytes_count; | ||
1445 | pbdb->data_block_ptr = temp; | ||
1446 | pbdb->trc_data_block_ptr = TRC_POINTER(temp); | ||
1447 | |||
1448 | pFCB = tp->tx_fcb_curr[queue]; | ||
1449 | tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr; | ||
1450 | |||
1451 | return (pFCB); | ||
1452 | } | ||
1453 | |||
1454 | static int smctr_get_upstream_neighbor_addr(struct net_device *dev) | ||
1455 | { | ||
1456 | smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS); | ||
1457 | |||
1458 | return(smctr_wait_cmd(dev)); | ||
1459 | } | ||
1460 | |||
1461 | static int smctr_hardware_send_packet(struct net_device *dev, | ||
1462 | struct net_local *tp) | ||
1463 | { | ||
1464 | struct tr_statistics *tstat = &tp->MacStat; | ||
1465 | struct sk_buff *skb; | ||
1466 | FCBlock *fcb; | ||
1467 | |||
1468 | if(smctr_debug > 10) | ||
1469 | printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name); | ||
1470 | |||
1471 | if(tp->status != OPEN) | ||
1472 | return (-1); | ||
1473 | |||
1474 | if(tp->monitor_state_ready != 1) | ||
1475 | return (-1); | ||
1476 | |||
1477 | for(;;) | ||
1478 | { | ||
1479 | /* Send first buffer from queue */ | ||
1480 | skb = skb_dequeue(&tp->SendSkbQueue); | ||
1481 | if(skb == NULL) | ||
1482 | return (-1); | ||
1483 | |||
1484 | tp->QueueSkb++; | ||
1485 | |||
1486 | if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) return (-1); | ||
1487 | |||
1488 | smctr_enable_16bit(dev); | ||
1489 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
1490 | |||
1491 | if((fcb = smctr_get_tx_fcb(dev, NON_MAC_QUEUE, skb->len)) | ||
1492 | == (FCBlock *)(-1L)) | ||
1493 | { | ||
1494 | smctr_disable_16bit(dev); | ||
1495 | return (-1); | ||
1496 | } | ||
1497 | |||
1498 | smctr_tx_move_frame(dev, skb, | ||
1499 | (__u8 *)fcb->bdb_ptr->data_block_ptr, skb->len); | ||
1500 | |||
1501 | smctr_set_page(dev, (__u8 *)fcb); | ||
1502 | |||
1503 | smctr_trc_send_packet(dev, fcb, NON_MAC_QUEUE); | ||
1504 | dev_kfree_skb(skb); | ||
1505 | |||
1506 | tstat->tx_packets++; | ||
1507 | |||
1508 | smctr_disable_16bit(dev); | ||
1509 | } | ||
1510 | |||
1511 | return (0); | ||
1512 | } | ||
1513 | |||
1514 | static int smctr_init_acbs(struct net_device *dev) | ||
1515 | { | ||
1516 | struct net_local *tp = netdev_priv(dev); | ||
1517 | unsigned int i; | ||
1518 | ACBlock *acb; | ||
1519 | |||
1520 | if(smctr_debug > 10) | ||
1521 | printk(KERN_DEBUG "%s: smctr_init_acbs\n", dev->name); | ||
1522 | |||
1523 | acb = tp->acb_head; | ||
1524 | acb->cmd_done_status = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL); | ||
1525 | acb->cmd_info = ACB_CHAIN_END; | ||
1526 | acb->cmd = 0; | ||
1527 | acb->subcmd = 0; | ||
1528 | acb->data_offset_lo = 0; | ||
1529 | acb->data_offset_hi = 0; | ||
1530 | acb->next_ptr | ||
1531 | = (ACBlock *)(((char *)acb) + sizeof(ACBlock)); | ||
1532 | acb->trc_next_ptr = TRC_POINTER(acb->next_ptr); | ||
1533 | |||
1534 | for(i = 1; i < tp->num_acbs; i++) | ||
1535 | { | ||
1536 | acb = acb->next_ptr; | ||
1537 | acb->cmd_done_status | ||
1538 | = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL); | ||
1539 | acb->cmd_info = ACB_CHAIN_END; | ||
1540 | acb->cmd = 0; | ||
1541 | acb->subcmd = 0; | ||
1542 | acb->data_offset_lo = 0; | ||
1543 | acb->data_offset_hi = 0; | ||
1544 | acb->next_ptr | ||
1545 | = (ACBlock *)(((char *)acb) + sizeof(ACBlock)); | ||
1546 | acb->trc_next_ptr = TRC_POINTER(acb->next_ptr); | ||
1547 | } | ||
1548 | |||
1549 | acb->next_ptr = tp->acb_head; | ||
1550 | acb->trc_next_ptr = TRC_POINTER(tp->acb_head); | ||
1551 | tp->acb_next = tp->acb_head->next_ptr; | ||
1552 | tp->acb_curr = tp->acb_head->next_ptr; | ||
1553 | tp->num_acbs_used = 0; | ||
1554 | |||
1555 | return (0); | ||
1556 | } | ||
1557 | |||
1558 | static int smctr_init_adapter(struct net_device *dev) | ||
1559 | { | ||
1560 | struct net_local *tp = netdev_priv(dev); | ||
1561 | int err; | ||
1562 | |||
1563 | if(smctr_debug > 10) | ||
1564 | printk(KERN_DEBUG "%s: smctr_init_adapter\n", dev->name); | ||
1565 | |||
1566 | tp->status = CLOSED; | ||
1567 | tp->page_offset_mask = (tp->ram_usable * 1024) - 1; | ||
1568 | skb_queue_head_init(&tp->SendSkbQueue); | ||
1569 | tp->QueueSkb = MAX_TX_QUEUE; | ||
1570 | |||
1571 | if(!(tp->group_address_0 & 0x0080)) | ||
1572 | tp->group_address_0 |= 0x00C0; | ||
1573 | |||
1574 | if(!(tp->functional_address_0 & 0x00C0)) | ||
1575 | tp->functional_address_0 |= 0x00C0; | ||
1576 | |||
1577 | tp->functional_address[0] &= 0xFF7F; | ||
1578 | |||
1579 | if(tp->authorized_function_classes == 0) | ||
1580 | tp->authorized_function_classes = 0x7FFF; | ||
1581 | |||
1582 | if(tp->authorized_access_priority == 0) | ||
1583 | tp->authorized_access_priority = 0x06; | ||
1584 | |||
1585 | smctr_disable_bic_int(dev); | ||
1586 | smctr_set_trc_reset(dev->base_addr); | ||
1587 | |||
1588 | smctr_enable_16bit(dev); | ||
1589 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
1590 | |||
1591 | if(smctr_checksum_firmware(dev)) | ||
1592 | { | ||
1593 | printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); return (-ENOENT); | ||
1594 | } | ||
1595 | |||
1596 | if((err = smctr_ram_memory_test(dev))) | ||
1597 | { | ||
1598 | printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name); | ||
1599 | return (-EIO); | ||
1600 | } | ||
1601 | |||
1602 | smctr_set_rx_look_ahead(dev); | ||
1603 | smctr_load_node_addr(dev); | ||
1604 | |||
1605 | /* Initialize adapter for Internal Self Test. */ | ||
1606 | smctr_reset_adapter(dev); | ||
1607 | if((err = smctr_init_card_real(dev))) | ||
1608 | { | ||
1609 | printk(KERN_ERR "%s: Initialization of card failed (%d)\n", | ||
1610 | dev->name, err); | ||
1611 | return (-EINVAL); | ||
1612 | } | ||
1613 | |||
1614 | /* This routine clobbers the TRC's internal registers. */ | ||
1615 | if((err = smctr_internal_self_test(dev))) | ||
1616 | { | ||
1617 | printk(KERN_ERR "%s: Card failed internal self test (%d)\n", | ||
1618 | dev->name, err); | ||
1619 | return (-EINVAL); | ||
1620 | } | ||
1621 | |||
1622 | /* Re-Initialize adapter's internal registers */ | ||
1623 | smctr_reset_adapter(dev); | ||
1624 | if((err = smctr_init_card_real(dev))) | ||
1625 | { | ||
1626 | printk(KERN_ERR "%s: Initialization of card failed (%d)\n", | ||
1627 | dev->name, err); | ||
1628 | return (-EINVAL); | ||
1629 | } | ||
1630 | |||
1631 | smctr_enable_bic_int(dev); | ||
1632 | |||
1633 | if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) | ||
1634 | return (err); | ||
1635 | |||
1636 | smctr_disable_16bit(dev); | ||
1637 | |||
1638 | return (0); | ||
1639 | } | ||
1640 | |||
1641 | static int smctr_init_card_real(struct net_device *dev) | ||
1642 | { | ||
1643 | struct net_local *tp = netdev_priv(dev); | ||
1644 | int err = 0; | ||
1645 | |||
1646 | if(smctr_debug > 10) | ||
1647 | printk(KERN_DEBUG "%s: smctr_init_card_real\n", dev->name); | ||
1648 | |||
1649 | tp->sh_mem_used = 0; | ||
1650 | tp->num_acbs = NUM_OF_ACBS; | ||
1651 | |||
1652 | /* Range Check Max Packet Size */ | ||
1653 | if(tp->max_packet_size < 256) | ||
1654 | tp->max_packet_size = 256; | ||
1655 | else | ||
1656 | { | ||
1657 | if(tp->max_packet_size > NON_MAC_TX_BUFFER_MEMORY) | ||
1658 | tp->max_packet_size = NON_MAC_TX_BUFFER_MEMORY; | ||
1659 | } | ||
1660 | |||
1661 | tp->num_of_tx_buffs = (NON_MAC_TX_BUFFER_MEMORY | ||
1662 | / tp->max_packet_size) - 1; | ||
1663 | |||
1664 | if(tp->num_of_tx_buffs > NUM_NON_MAC_TX_FCBS) | ||
1665 | tp->num_of_tx_buffs = NUM_NON_MAC_TX_FCBS; | ||
1666 | else | ||
1667 | { | ||
1668 | if(tp->num_of_tx_buffs == 0) | ||
1669 | tp->num_of_tx_buffs = 1; | ||
1670 | } | ||
1671 | |||
1672 | /* Tx queue constants */ | ||
1673 | tp->num_tx_fcbs [BUG_QUEUE] = NUM_BUG_TX_FCBS; | ||
1674 | tp->num_tx_bdbs [BUG_QUEUE] = NUM_BUG_TX_BDBS; | ||
1675 | tp->tx_buff_size [BUG_QUEUE] = BUG_TX_BUFFER_MEMORY; | ||
1676 | tp->tx_buff_used [BUG_QUEUE] = 0; | ||
1677 | tp->tx_queue_status [BUG_QUEUE] = NOT_TRANSMITING; | ||
1678 | |||
1679 | tp->num_tx_fcbs [MAC_QUEUE] = NUM_MAC_TX_FCBS; | ||
1680 | tp->num_tx_bdbs [MAC_QUEUE] = NUM_MAC_TX_BDBS; | ||
1681 | tp->tx_buff_size [MAC_QUEUE] = MAC_TX_BUFFER_MEMORY; | ||
1682 | tp->tx_buff_used [MAC_QUEUE] = 0; | ||
1683 | tp->tx_queue_status [MAC_QUEUE] = NOT_TRANSMITING; | ||
1684 | |||
1685 | tp->num_tx_fcbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_FCBS; | ||
1686 | tp->num_tx_bdbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_BDBS; | ||
1687 | tp->tx_buff_size [NON_MAC_QUEUE] = NON_MAC_TX_BUFFER_MEMORY; | ||
1688 | tp->tx_buff_used [NON_MAC_QUEUE] = 0; | ||
1689 | tp->tx_queue_status [NON_MAC_QUEUE] = NOT_TRANSMITING; | ||
1690 | |||
1691 | /* Receive Queue Constants */ | ||
1692 | tp->num_rx_fcbs[MAC_QUEUE] = NUM_MAC_RX_FCBS; | ||
1693 | tp->num_rx_bdbs[MAC_QUEUE] = NUM_MAC_RX_BDBS; | ||
1694 | |||
1695 | if(tp->extra_info & CHIP_REV_MASK) | ||
1696 | tp->num_rx_fcbs[NON_MAC_QUEUE] = 78; /* 825 Rev. XE */ | ||
1697 | else | ||
1698 | tp->num_rx_fcbs[NON_MAC_QUEUE] = 7; /* 825 Rev. XD */ | ||
1699 | |||
1700 | tp->num_rx_bdbs[NON_MAC_QUEUE] = smctr_get_num_rx_bdbs(dev); | ||
1701 | |||
1702 | smctr_alloc_shared_memory(dev); | ||
1703 | smctr_init_shared_memory(dev); | ||
1704 | |||
1705 | if((err = smctr_issue_init_timers_cmd(dev))) | ||
1706 | return (err); | ||
1707 | |||
1708 | if((err = smctr_issue_init_txrx_cmd(dev))) | ||
1709 | { | ||
1710 | printk(KERN_ERR "%s: Hardware failure\n", dev->name); | ||
1711 | return (err); | ||
1712 | } | ||
1713 | |||
1714 | return (0); | ||
1715 | } | ||
1716 | |||
1717 | static int smctr_init_rx_bdbs(struct net_device *dev) | ||
1718 | { | ||
1719 | struct net_local *tp = netdev_priv(dev); | ||
1720 | unsigned int i, j; | ||
1721 | BDBlock *bdb; | ||
1722 | __u16 *buf; | ||
1723 | |||
1724 | if(smctr_debug > 10) | ||
1725 | printk(KERN_DEBUG "%s: smctr_init_rx_bdbs\n", dev->name); | ||
1726 | |||
1727 | for(i = 0; i < NUM_RX_QS_USED; i++) | ||
1728 | { | ||
1729 | bdb = tp->rx_bdb_head[i]; | ||
1730 | buf = tp->rx_buff_head[i]; | ||
1731 | bdb->info = (BDB_CHAIN_END | BDB_NO_WARNING); | ||
1732 | bdb->buffer_length = RX_DATA_BUFFER_SIZE; | ||
1733 | bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); | ||
1734 | bdb->data_block_ptr = buf; | ||
1735 | bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); | ||
1736 | |||
1737 | if(i == NON_MAC_QUEUE) | ||
1738 | bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf); | ||
1739 | else | ||
1740 | bdb->trc_data_block_ptr = TRC_POINTER(buf); | ||
1741 | |||
1742 | for(j = 1; j < tp->num_rx_bdbs[i]; j++) | ||
1743 | { | ||
1744 | bdb->next_ptr->back_ptr = bdb; | ||
1745 | bdb = bdb->next_ptr; | ||
1746 | buf = (__u16 *)((char *)buf + RX_DATA_BUFFER_SIZE); | ||
1747 | bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); | ||
1748 | bdb->buffer_length = RX_DATA_BUFFER_SIZE; | ||
1749 | bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); | ||
1750 | bdb->data_block_ptr = buf; | ||
1751 | bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); | ||
1752 | |||
1753 | if(i == NON_MAC_QUEUE) | ||
1754 | bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf); | ||
1755 | else | ||
1756 | bdb->trc_data_block_ptr = TRC_POINTER(buf); | ||
1757 | } | ||
1758 | |||
1759 | bdb->next_ptr = tp->rx_bdb_head[i]; | ||
1760 | bdb->trc_next_ptr = TRC_POINTER(tp->rx_bdb_head[i]); | ||
1761 | |||
1762 | tp->rx_bdb_head[i]->back_ptr = bdb; | ||
1763 | tp->rx_bdb_curr[i] = tp->rx_bdb_head[i]->next_ptr; | ||
1764 | } | ||
1765 | |||
1766 | return (0); | ||
1767 | } | ||
1768 | |||
1769 | static int smctr_init_rx_fcbs(struct net_device *dev) | ||
1770 | { | ||
1771 | struct net_local *tp = netdev_priv(dev); | ||
1772 | unsigned int i, j; | ||
1773 | FCBlock *fcb; | ||
1774 | |||
1775 | for(i = 0; i < NUM_RX_QS_USED; i++) | ||
1776 | { | ||
1777 | fcb = tp->rx_fcb_head[i]; | ||
1778 | fcb->frame_status = 0; | ||
1779 | fcb->frame_length = 0; | ||
1780 | fcb->info = FCB_CHAIN_END; | ||
1781 | fcb->next_ptr = (FCBlock *)(((char*)fcb) + sizeof(FCBlock)); | ||
1782 | if(i == NON_MAC_QUEUE) | ||
1783 | fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr); | ||
1784 | else | ||
1785 | fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); | ||
1786 | |||
1787 | for(j = 1; j < tp->num_rx_fcbs[i]; j++) | ||
1788 | { | ||
1789 | fcb->next_ptr->back_ptr = fcb; | ||
1790 | fcb = fcb->next_ptr; | ||
1791 | fcb->frame_status = 0; | ||
1792 | fcb->frame_length = 0; | ||
1793 | fcb->info = FCB_WARNING; | ||
1794 | fcb->next_ptr | ||
1795 | = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); | ||
1796 | |||
1797 | if(i == NON_MAC_QUEUE) | ||
1798 | fcb->trc_next_ptr | ||
1799 | = RX_FCB_TRC_POINTER(fcb->next_ptr); | ||
1800 | else | ||
1801 | fcb->trc_next_ptr | ||
1802 | = TRC_POINTER(fcb->next_ptr); | ||
1803 | } | ||
1804 | |||
1805 | fcb->next_ptr = tp->rx_fcb_head[i]; | ||
1806 | |||
1807 | if(i == NON_MAC_QUEUE) | ||
1808 | fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr); | ||
1809 | else | ||
1810 | fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); | ||
1811 | |||
1812 | tp->rx_fcb_head[i]->back_ptr = fcb; | ||
1813 | tp->rx_fcb_curr[i] = tp->rx_fcb_head[i]->next_ptr; | ||
1814 | } | ||
1815 | |||
1816 | return(0); | ||
1817 | } | ||
1818 | |||
1819 | static int smctr_init_shared_memory(struct net_device *dev) | ||
1820 | { | ||
1821 | struct net_local *tp = netdev_priv(dev); | ||
1822 | unsigned int i; | ||
1823 | __u32 *iscpb; | ||
1824 | |||
1825 | if(smctr_debug > 10) | ||
1826 | printk(KERN_DEBUG "%s: smctr_init_shared_memory\n", dev->name); | ||
1827 | |||
1828 | smctr_set_page(dev, (__u8 *)(unsigned int)tp->iscpb_ptr); | ||
1829 | |||
1830 | /* Initialize Initial System Configuration Point. (ISCP) */ | ||
1831 | iscpb = (__u32 *)PAGE_POINTER(&tp->iscpb_ptr->trc_scgb_ptr); | ||
1832 | *iscpb = (__u32)(SWAP_WORDS(TRC_POINTER(tp->scgb_ptr))); | ||
1833 | |||
1834 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
1835 | |||
1836 | /* Initialize System Configuration Pointers. (SCP) */ | ||
1837 | tp->scgb_ptr->config = (SCGB_ADDRESS_POINTER_FORMAT | ||
1838 | | SCGB_MULTI_WORD_CONTROL | SCGB_DATA_FORMAT | ||
1839 | | SCGB_BURST_LENGTH); | ||
1840 | |||
1841 | tp->scgb_ptr->trc_sclb_ptr = TRC_POINTER(tp->sclb_ptr); | ||
1842 | tp->scgb_ptr->trc_acb_ptr = TRC_POINTER(tp->acb_head); | ||
1843 | tp->scgb_ptr->trc_isb_ptr = TRC_POINTER(tp->isb_ptr); | ||
1844 | tp->scgb_ptr->isbsiz = (sizeof(ISBlock)) - 2; | ||
1845 | |||
1846 | /* Initialize System Control Block. (SCB) */ | ||
1847 | tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_NOP; | ||
1848 | tp->sclb_ptr->iack_code = 0; | ||
1849 | tp->sclb_ptr->resume_control = 0; | ||
1850 | tp->sclb_ptr->int_mask_control = 0; | ||
1851 | tp->sclb_ptr->int_mask_state = 0; | ||
1852 | |||
1853 | /* Initialize Interrupt Status Block. (ISB) */ | ||
1854 | for(i = 0; i < NUM_OF_INTERRUPTS; i++) | ||
1855 | { | ||
1856 | tp->isb_ptr->IStatus[i].IType = 0xf0; | ||
1857 | tp->isb_ptr->IStatus[i].ISubtype = 0; | ||
1858 | } | ||
1859 | |||
1860 | tp->current_isb_index = 0; | ||
1861 | |||
1862 | /* Initialize Action Command Block. (ACB) */ | ||
1863 | smctr_init_acbs(dev); | ||
1864 | |||
1865 | /* Initialize transmit FCB's and BDB's. */ | ||
1866 | smctr_link_tx_fcbs_to_bdbs(dev); | ||
1867 | smctr_init_tx_bdbs(dev); | ||
1868 | smctr_init_tx_fcbs(dev); | ||
1869 | |||
1870 | /* Initialize receive FCB's and BDB's. */ | ||
1871 | smctr_init_rx_bdbs(dev); | ||
1872 | smctr_init_rx_fcbs(dev); | ||
1873 | |||
1874 | return (0); | ||
1875 | } | ||
1876 | |||
1877 | static int smctr_init_tx_bdbs(struct net_device *dev) | ||
1878 | { | ||
1879 | struct net_local *tp = netdev_priv(dev); | ||
1880 | unsigned int i, j; | ||
1881 | BDBlock *bdb; | ||
1882 | |||
1883 | for(i = 0; i < NUM_TX_QS_USED; i++) | ||
1884 | { | ||
1885 | bdb = tp->tx_bdb_head[i]; | ||
1886 | bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); | ||
1887 | bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); | ||
1888 | bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); | ||
1889 | |||
1890 | for(j = 1; j < tp->num_tx_bdbs[i]; j++) | ||
1891 | { | ||
1892 | bdb->next_ptr->back_ptr = bdb; | ||
1893 | bdb = bdb->next_ptr; | ||
1894 | bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); | ||
1895 | bdb->next_ptr | ||
1896 | = (BDBlock *)(((char *)bdb) + sizeof( BDBlock)); bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); | ||
1897 | } | ||
1898 | |||
1899 | bdb->next_ptr = tp->tx_bdb_head[i]; | ||
1900 | bdb->trc_next_ptr = TRC_POINTER(tp->tx_bdb_head[i]); | ||
1901 | tp->tx_bdb_head[i]->back_ptr = bdb; | ||
1902 | } | ||
1903 | |||
1904 | return (0); | ||
1905 | } | ||
1906 | |||
1907 | static int smctr_init_tx_fcbs(struct net_device *dev) | ||
1908 | { | ||
1909 | struct net_local *tp = netdev_priv(dev); | ||
1910 | unsigned int i, j; | ||
1911 | FCBlock *fcb; | ||
1912 | |||
1913 | for(i = 0; i < NUM_TX_QS_USED; i++) | ||
1914 | { | ||
1915 | fcb = tp->tx_fcb_head[i]; | ||
1916 | fcb->frame_status = 0; | ||
1917 | fcb->frame_length = 0; | ||
1918 | fcb->info = FCB_CHAIN_END; | ||
1919 | fcb->next_ptr = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); | ||
1920 | fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); | ||
1921 | |||
1922 | for(j = 1; j < tp->num_tx_fcbs[i]; j++) | ||
1923 | { | ||
1924 | fcb->next_ptr->back_ptr = fcb; | ||
1925 | fcb = fcb->next_ptr; | ||
1926 | fcb->frame_status = 0; | ||
1927 | fcb->frame_length = 0; | ||
1928 | fcb->info = FCB_CHAIN_END; | ||
1929 | fcb->next_ptr | ||
1930 | = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); | ||
1931 | fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); | ||
1932 | } | ||
1933 | |||
1934 | fcb->next_ptr = tp->tx_fcb_head[i]; | ||
1935 | fcb->trc_next_ptr = TRC_POINTER(tp->tx_fcb_head[i]); | ||
1936 | |||
1937 | tp->tx_fcb_head[i]->back_ptr = fcb; | ||
1938 | tp->tx_fcb_end[i] = tp->tx_fcb_head[i]->next_ptr; | ||
1939 | tp->tx_fcb_curr[i] = tp->tx_fcb_head[i]->next_ptr; | ||
1940 | tp->num_tx_fcbs_used[i] = 0; | ||
1941 | } | ||
1942 | |||
1943 | return (0); | ||
1944 | } | ||
1945 | |||
1946 | static int smctr_internal_self_test(struct net_device *dev) | ||
1947 | { | ||
1948 | struct net_local *tp = netdev_priv(dev); | ||
1949 | int err; | ||
1950 | |||
1951 | if((err = smctr_issue_test_internal_rom_cmd(dev))) | ||
1952 | return (err); | ||
1953 | |||
1954 | if((err = smctr_wait_cmd(dev))) | ||
1955 | return (err); | ||
1956 | |||
1957 | if(tp->acb_head->cmd_done_status & 0xff) | ||
1958 | return (-1); | ||
1959 | |||
1960 | if((err = smctr_issue_test_hic_cmd(dev))) | ||
1961 | return (err); | ||
1962 | |||
1963 | if((err = smctr_wait_cmd(dev))) | ||
1964 | return (err); | ||
1965 | |||
1966 | if(tp->acb_head->cmd_done_status & 0xff) | ||
1967 | return (-1); | ||
1968 | |||
1969 | if((err = smctr_issue_test_mac_reg_cmd(dev))) | ||
1970 | return (err); | ||
1971 | |||
1972 | if((err = smctr_wait_cmd(dev))) | ||
1973 | return (err); | ||
1974 | |||
1975 | if(tp->acb_head->cmd_done_status & 0xff) | ||
1976 | return (-1); | ||
1977 | |||
1978 | return (0); | ||
1979 | } | ||
1980 | |||
1981 | /* | ||
1982 | * The typical workload of the driver: Handle the network interface interrupts. | ||
1983 | */ | ||
1984 | static irqreturn_t smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1985 | { | ||
1986 | struct net_device *dev = dev_id; | ||
1987 | struct net_local *tp; | ||
1988 | int ioaddr; | ||
1989 | __u16 interrupt_unmask_bits = 0, interrupt_ack_code = 0xff00; | ||
1990 | __u16 err1, err = NOT_MY_INTERRUPT; | ||
1991 | __u8 isb_type, isb_subtype; | ||
1992 | __u16 isb_index; | ||
1993 | |||
1994 | if(dev == NULL) | ||
1995 | { | ||
1996 | printk(KERN_CRIT "%s: irq %d for unknown device.\n", dev->name, irq); | ||
1997 | return IRQ_NONE; | ||
1998 | } | ||
1999 | |||
2000 | ioaddr = dev->base_addr; | ||
2001 | tp = netdev_priv(dev); | ||
2002 | |||
2003 | |||
2004 | if(tp->status == NOT_INITIALIZED) | ||
2005 | return IRQ_NONE; | ||
2006 | |||
2007 | spin_lock(&tp->lock); | ||
2008 | |||
2009 | smctr_disable_bic_int(dev); | ||
2010 | smctr_enable_16bit(dev); | ||
2011 | |||
2012 | smctr_clear_int(dev); | ||
2013 | |||
2014 | /* First read the LSB */ | ||
2015 | while((tp->isb_ptr->IStatus[tp->current_isb_index].IType & 0xf0) == 0) | ||
2016 | { | ||
2017 | isb_index = tp->current_isb_index; | ||
2018 | isb_type = tp->isb_ptr->IStatus[isb_index].IType; | ||
2019 | isb_subtype = tp->isb_ptr->IStatus[isb_index].ISubtype; | ||
2020 | |||
2021 | (tp->current_isb_index)++; | ||
2022 | if(tp->current_isb_index == NUM_OF_INTERRUPTS) | ||
2023 | tp->current_isb_index = 0; | ||
2024 | |||
2025 | if(isb_type >= 0x10) | ||
2026 | { | ||
2027 | smctr_disable_16bit(dev); | ||
2028 | spin_unlock(&tp->lock); | ||
2029 | return IRQ_HANDLED; | ||
2030 | } | ||
2031 | |||
2032 | err = HARDWARE_FAILED; | ||
2033 | interrupt_ack_code = isb_index; | ||
2034 | tp->isb_ptr->IStatus[isb_index].IType |= 0xf0; | ||
2035 | |||
2036 | interrupt_unmask_bits |= (1 << (__u16)isb_type); | ||
2037 | |||
2038 | switch(isb_type) | ||
2039 | { | ||
2040 | case ISB_IMC_MAC_TYPE_3: | ||
2041 | smctr_disable_16bit(dev); | ||
2042 | |||
2043 | switch(isb_subtype) | ||
2044 | { | ||
2045 | case 0: | ||
2046 | tp->monitor_state = MS_MONITOR_FSM_INACTIVE; | ||
2047 | break; | ||
2048 | |||
2049 | case 1: | ||
2050 | tp->monitor_state = MS_REPEAT_BEACON_STATE; | ||
2051 | break; | ||
2052 | |||
2053 | case 2: | ||
2054 | tp->monitor_state = MS_REPEAT_CLAIM_TOKEN_STATE; | ||
2055 | break; | ||
2056 | |||
2057 | case 3: | ||
2058 | tp->monitor_state = MS_TRANSMIT_CLAIM_TOKEN_STATE; break; | ||
2059 | |||
2060 | case 4: | ||
2061 | tp->monitor_state = MS_STANDBY_MONITOR_STATE; | ||
2062 | break; | ||
2063 | |||
2064 | case 5: | ||
2065 | tp->monitor_state = MS_TRANSMIT_BEACON_STATE; | ||
2066 | break; | ||
2067 | |||
2068 | case 6: | ||
2069 | tp->monitor_state = MS_ACTIVE_MONITOR_STATE; | ||
2070 | break; | ||
2071 | |||
2072 | case 7: | ||
2073 | tp->monitor_state = MS_TRANSMIT_RING_PURGE_STATE; | ||
2074 | break; | ||
2075 | |||
2076 | case 8: /* diagnostic state */ | ||
2077 | break; | ||
2078 | |||
2079 | case 9: | ||
2080 | tp->monitor_state = MS_BEACON_TEST_STATE; | ||
2081 | if(smctr_lobe_media_test(dev)) | ||
2082 | { | ||
2083 | tp->ring_status_flags = RING_STATUS_CHANGED; | ||
2084 | tp->ring_status = AUTO_REMOVAL_ERROR; | ||
2085 | smctr_ring_status_chg(dev); | ||
2086 | smctr_bypass_state(dev); | ||
2087 | } | ||
2088 | else | ||
2089 | smctr_issue_insert_cmd(dev); | ||
2090 | break; | ||
2091 | |||
2092 | /* case 0x0a-0xff, illegal states */ | ||
2093 | default: | ||
2094 | break; | ||
2095 | } | ||
2096 | |||
2097 | tp->ring_status_flags = MONITOR_STATE_CHANGED; | ||
2098 | err = smctr_ring_status_chg(dev); | ||
2099 | |||
2100 | smctr_enable_16bit(dev); | ||
2101 | break; | ||
2102 | |||
2103 | /* Type 0x02 - MAC Error Counters Interrupt | ||
2104 | * One or more MAC Error Counter is half full | ||
2105 | * MAC Error Counters | ||
2106 | * Lost_FR_Error_Counter | ||
2107 | * RCV_Congestion_Counter | ||
2108 | * FR_copied_Error_Counter | ||
2109 | * FREQ_Error_Counter | ||
2110 | * Token_Error_Counter | ||
2111 | * Line_Error_Counter | ||
2112 | * Internal_Error_Count | ||
2113 | */ | ||
2114 | case ISB_IMC_MAC_ERROR_COUNTERS: | ||
2115 | /* Read 802.5 Error Counters */ | ||
2116 | err = smctr_issue_read_ring_status_cmd(dev); | ||
2117 | break; | ||
2118 | |||
2119 | /* Type 0x04 - MAC Type 2 Interrupt | ||
2120 | * HOST needs to enqueue MAC Frame for transmission | ||
2121 | * SubType Bit 15 - RQ_INIT_PDU( Request Initialization) * Changed from RQ_INIT_PDU to | ||
2122 | * TRC_Status_Changed_Indicate | ||
2123 | */ | ||
2124 | case ISB_IMC_MAC_TYPE_2: | ||
2125 | err = smctr_issue_read_ring_status_cmd(dev); | ||
2126 | break; | ||
2127 | |||
2128 | |||
2129 | /* Type 0x05 - TX Frame Interrupt (FI). */ | ||
2130 | case ISB_IMC_TX_FRAME: | ||
2131 | /* BUG QUEUE for TRC stuck receive BUG */ | ||
2132 | if(isb_subtype & TX_PENDING_PRIORITY_2) | ||
2133 | { | ||
2134 | if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS) | ||
2135 | break; | ||
2136 | } | ||
2137 | |||
2138 | /* NON-MAC frames only */ | ||
2139 | if(isb_subtype & TX_PENDING_PRIORITY_1) | ||
2140 | { | ||
2141 | if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS) | ||
2142 | break; | ||
2143 | } | ||
2144 | |||
2145 | /* MAC frames only */ | ||
2146 | if(isb_subtype & TX_PENDING_PRIORITY_0) | ||
2147 | err = smctr_tx_complete(dev, MAC_QUEUE); break; | ||
2148 | |||
2149 | /* Type 0x06 - TX END OF QUEUE (FE) */ | ||
2150 | case ISB_IMC_END_OF_TX_QUEUE: | ||
2151 | /* BUG queue */ | ||
2152 | if(isb_subtype & TX_PENDING_PRIORITY_2) | ||
2153 | { | ||
2154 | /* ok to clear Receive FIFO overrun | ||
2155 | * imask send_BUG now completes. | ||
2156 | */ | ||
2157 | interrupt_unmask_bits |= 0x800; | ||
2158 | |||
2159 | tp->tx_queue_status[BUG_QUEUE] = NOT_TRANSMITING; | ||
2160 | if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS) | ||
2161 | break; | ||
2162 | if((err = smctr_restart_tx_chain(dev, BUG_QUEUE)) != SUCCESS) | ||
2163 | break; | ||
2164 | } | ||
2165 | |||
2166 | /* NON-MAC queue only */ | ||
2167 | if(isb_subtype & TX_PENDING_PRIORITY_1) | ||
2168 | { | ||
2169 | tp->tx_queue_status[NON_MAC_QUEUE] = NOT_TRANSMITING; | ||
2170 | if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS) | ||
2171 | break; | ||
2172 | if((err = smctr_restart_tx_chain(dev, NON_MAC_QUEUE)) != SUCCESS) | ||
2173 | break; | ||
2174 | } | ||
2175 | |||
2176 | /* MAC queue only */ | ||
2177 | if(isb_subtype & TX_PENDING_PRIORITY_0) | ||
2178 | { | ||
2179 | tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; | ||
2180 | if((err = smctr_tx_complete(dev, MAC_QUEUE)) != SUCCESS) | ||
2181 | break; | ||
2182 | |||
2183 | err = smctr_restart_tx_chain(dev, MAC_QUEUE); | ||
2184 | } | ||
2185 | break; | ||
2186 | |||
2187 | /* Type 0x07 - NON-MAC RX Resource Interrupt | ||
2188 | * Subtype bit 12 - (BW) BDB warning | ||
2189 | * Subtype bit 13 - (FW) FCB warning | ||
2190 | * Subtype bit 14 - (BE) BDB End of chain | ||
2191 | * Subtype bit 15 - (FE) FCB End of chain | ||
2192 | */ | ||
2193 | case ISB_IMC_NON_MAC_RX_RESOURCE: | ||
2194 | tp->rx_fifo_overrun_count = 0; | ||
2195 | tp->receive_queue_number = NON_MAC_QUEUE; | ||
2196 | err1 = smctr_rx_frame(dev); | ||
2197 | |||
2198 | if(isb_subtype & NON_MAC_RX_RESOURCE_FE) | ||
2199 | { | ||
2200 | if((err = smctr_issue_resume_rx_fcb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break; | ||
2201 | |||
2202 | if(tp->ptr_rx_fcb_overruns) | ||
2203 | (*tp->ptr_rx_fcb_overruns)++; | ||
2204 | } | ||
2205 | |||
2206 | if(isb_subtype & NON_MAC_RX_RESOURCE_BE) | ||
2207 | { | ||
2208 | if((err = smctr_issue_resume_rx_bdb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break; | ||
2209 | |||
2210 | if(tp->ptr_rx_bdb_overruns) | ||
2211 | (*tp->ptr_rx_bdb_overruns)++; | ||
2212 | } | ||
2213 | err = err1; | ||
2214 | break; | ||
2215 | |||
2216 | /* Type 0x08 - MAC RX Resource Interrupt | ||
2217 | * Subtype bit 12 - (BW) BDB warning | ||
2218 | * Subtype bit 13 - (FW) FCB warning | ||
2219 | * Subtype bit 14 - (BE) BDB End of chain | ||
2220 | * Subtype bit 15 - (FE) FCB End of chain | ||
2221 | */ | ||
2222 | case ISB_IMC_MAC_RX_RESOURCE: | ||
2223 | tp->receive_queue_number = MAC_QUEUE; | ||
2224 | err1 = smctr_rx_frame(dev); | ||
2225 | |||
2226 | if(isb_subtype & MAC_RX_RESOURCE_FE) | ||
2227 | { | ||
2228 | if((err = smctr_issue_resume_rx_fcb_cmd( dev, MAC_QUEUE)) != SUCCESS) | ||
2229 | break; | ||
2230 | |||
2231 | if(tp->ptr_rx_fcb_overruns) | ||
2232 | (*tp->ptr_rx_fcb_overruns)++; | ||
2233 | } | ||
2234 | |||
2235 | if(isb_subtype & MAC_RX_RESOURCE_BE) | ||
2236 | { | ||
2237 | if((err = smctr_issue_resume_rx_bdb_cmd( dev, MAC_QUEUE)) != SUCCESS) | ||
2238 | break; | ||
2239 | |||
2240 | if(tp->ptr_rx_bdb_overruns) | ||
2241 | (*tp->ptr_rx_bdb_overruns)++; | ||
2242 | } | ||
2243 | err = err1; | ||
2244 | break; | ||
2245 | |||
2246 | /* Type 0x09 - NON_MAC RX Frame Interrupt */ | ||
2247 | case ISB_IMC_NON_MAC_RX_FRAME: | ||
2248 | tp->rx_fifo_overrun_count = 0; | ||
2249 | tp->receive_queue_number = NON_MAC_QUEUE; | ||
2250 | err = smctr_rx_frame(dev); | ||
2251 | break; | ||
2252 | |||
2253 | /* Type 0x0A - MAC RX Frame Interrupt */ | ||
2254 | case ISB_IMC_MAC_RX_FRAME: | ||
2255 | tp->receive_queue_number = MAC_QUEUE; | ||
2256 | err = smctr_rx_frame(dev); | ||
2257 | break; | ||
2258 | |||
2259 | /* Type 0x0B - TRC status | ||
2260 | * TRC has encountered an error condition | ||
2261 | * subtype bit 14 - transmit FIFO underrun | ||
2262 | * subtype bit 15 - receive FIFO overrun | ||
2263 | */ | ||
2264 | case ISB_IMC_TRC_FIFO_STATUS: | ||
2265 | if(isb_subtype & TRC_FIFO_STATUS_TX_UNDERRUN) | ||
2266 | { | ||
2267 | if(tp->ptr_tx_fifo_underruns) | ||
2268 | (*tp->ptr_tx_fifo_underruns)++; | ||
2269 | } | ||
2270 | |||
2271 | if(isb_subtype & TRC_FIFO_STATUS_RX_OVERRUN) | ||
2272 | { | ||
2273 | /* update overrun stuck receive counter | ||
2274 | * if >= 3, has to clear it by sending | ||
2275 | * back to back frames. We pick | ||
2276 | * DAT(duplicate address MAC frame) | ||
2277 | */ | ||
2278 | tp->rx_fifo_overrun_count++; | ||
2279 | |||
2280 | if(tp->rx_fifo_overrun_count >= 3) | ||
2281 | { | ||
2282 | tp->rx_fifo_overrun_count = 0; | ||
2283 | |||
2284 | /* delay clearing fifo overrun | ||
2285 | * imask till send_BUG tx | ||
2286 | * complete posted | ||
2287 | */ | ||
2288 | interrupt_unmask_bits &= (~0x800); | ||
2289 | printk(KERN_CRIT "Jay please send bug\n");// smctr_send_bug(dev); | ||
2290 | } | ||
2291 | |||
2292 | if(tp->ptr_rx_fifo_overruns) | ||
2293 | (*tp->ptr_rx_fifo_overruns)++; | ||
2294 | } | ||
2295 | |||
2296 | err = SUCCESS; | ||
2297 | break; | ||
2298 | |||
2299 | /* Type 0x0C - Action Command Status Interrupt | ||
2300 | * Subtype bit 14 - CB end of command chain (CE) | ||
2301 | * Subtype bit 15 - CB command interrupt (CI) | ||
2302 | */ | ||
2303 | case ISB_IMC_COMMAND_STATUS: | ||
2304 | err = SUCCESS; | ||
2305 | if(tp->acb_head->cmd == ACB_CMD_HIC_NOP) | ||
2306 | { | ||
2307 | printk(KERN_ERR "i1\n"); | ||
2308 | smctr_disable_16bit(dev); | ||
2309 | |||
2310 | /* XXXXXXXXXXXXXXXXX */ | ||
2311 | /* err = UM_Interrupt(dev); */ | ||
2312 | |||
2313 | smctr_enable_16bit(dev); | ||
2314 | } | ||
2315 | else | ||
2316 | { | ||
2317 | if((tp->acb_head->cmd | ||
2318 | == ACB_CMD_READ_TRC_STATUS) | ||
2319 | && (tp->acb_head->subcmd | ||
2320 | == RW_TRC_STATUS_BLOCK)) | ||
2321 | { | ||
2322 | if(tp->ptr_bcn_type != 0) | ||
2323 | { | ||
2324 | *(tp->ptr_bcn_type) | ||
2325 | = (__u32)((SBlock *)tp->misc_command_data)->BCN_Type; | ||
2326 | } | ||
2327 | |||
2328 | if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & ERROR_COUNTERS_CHANGED) | ||
2329 | { | ||
2330 | smctr_update_err_stats(dev); | ||
2331 | } | ||
2332 | |||
2333 | if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & TI_NDIS_RING_STATUS_CHANGED) | ||
2334 | { | ||
2335 | tp->ring_status | ||
2336 | = ((SBlock*)tp->misc_command_data)->TI_NDIS_Ring_Status; | ||
2337 | smctr_disable_16bit(dev); | ||
2338 | err = smctr_ring_status_chg(dev); | ||
2339 | smctr_enable_16bit(dev); | ||
2340 | if((tp->ring_status & REMOVE_RECEIVED) | ||
2341 | && (tp->config_word0 & NO_AUTOREMOVE)) | ||
2342 | { | ||
2343 | smctr_issue_remove_cmd(dev); | ||
2344 | } | ||
2345 | |||
2346 | if(err != SUCCESS) | ||
2347 | { | ||
2348 | tp->acb_pending = 0; | ||
2349 | break; | ||
2350 | } | ||
2351 | } | ||
2352 | |||
2353 | if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & UNA_CHANGED) | ||
2354 | { | ||
2355 | if(tp->ptr_una) | ||
2356 | { | ||
2357 | tp->ptr_una[0] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[0]); | ||
2358 | tp->ptr_una[1] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[1]); | ||
2359 | tp->ptr_una[2] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[2]); | ||
2360 | } | ||
2361 | |||
2362 | } | ||
2363 | |||
2364 | if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & READY_TO_SEND_RQ_INIT) { | ||
2365 | err = smctr_send_rq_init(dev); | ||
2366 | } | ||
2367 | } | ||
2368 | } | ||
2369 | |||
2370 | tp->acb_pending = 0; | ||
2371 | break; | ||
2372 | |||
2373 | /* Type 0x0D - MAC Type 1 interrupt | ||
2374 | * Subtype -- 00 FR_BCN received at S12 | ||
2375 | * 01 FR_BCN received at S21 | ||
2376 | * 02 FR_DAT(DA=MA, A<>0) received at S21 | ||
2377 | * 03 TSM_EXP at S21 | ||
2378 | * 04 FR_REMOVE received at S42 | ||
2379 | * 05 TBR_EXP, BR_FLAG_SET at S42 | ||
2380 | * 06 TBT_EXP at S53 | ||
2381 | */ | ||
2382 | case ISB_IMC_MAC_TYPE_1: | ||
2383 | if(isb_subtype > 8) | ||
2384 | { | ||
2385 | err = HARDWARE_FAILED; | ||
2386 | break; | ||
2387 | } | ||
2388 | |||
2389 | err = SUCCESS; | ||
2390 | switch(isb_subtype) | ||
2391 | { | ||
2392 | case 0: | ||
2393 | tp->join_state = JS_BYPASS_STATE; | ||
2394 | if(tp->status != CLOSED) | ||
2395 | { | ||
2396 | tp->status = CLOSED; | ||
2397 | err = smctr_status_chg(dev); | ||
2398 | } | ||
2399 | break; | ||
2400 | |||
2401 | case 1: | ||
2402 | tp->join_state = JS_LOBE_TEST_STATE; | ||
2403 | break; | ||
2404 | |||
2405 | case 2: | ||
2406 | tp->join_state = JS_DETECT_MONITOR_PRESENT_STATE; | ||
2407 | break; | ||
2408 | |||
2409 | case 3: | ||
2410 | tp->join_state = JS_AWAIT_NEW_MONITOR_STATE; | ||
2411 | break; | ||
2412 | |||
2413 | case 4: | ||
2414 | tp->join_state = JS_DUPLICATE_ADDRESS_TEST_STATE; | ||
2415 | break; | ||
2416 | |||
2417 | case 5: | ||
2418 | tp->join_state = JS_NEIGHBOR_NOTIFICATION_STATE; | ||
2419 | break; | ||
2420 | |||
2421 | case 6: | ||
2422 | tp->join_state = JS_REQUEST_INITIALIZATION_STATE; | ||
2423 | break; | ||
2424 | |||
2425 | case 7: | ||
2426 | tp->join_state = JS_JOIN_COMPLETE_STATE; | ||
2427 | tp->status = OPEN; | ||
2428 | err = smctr_status_chg(dev); | ||
2429 | break; | ||
2430 | |||
2431 | case 8: | ||
2432 | tp->join_state = JS_BYPASS_WAIT_STATE; | ||
2433 | break; | ||
2434 | } | ||
2435 | break ; | ||
2436 | |||
2437 | /* Type 0x0E - TRC Initialization Sequence Interrupt | ||
2438 | * Subtype -- 00-FF Initializatin sequence complete | ||
2439 | */ | ||
2440 | case ISB_IMC_TRC_INTRNL_TST_STATUS: | ||
2441 | tp->status = INITIALIZED; | ||
2442 | smctr_disable_16bit(dev); | ||
2443 | err = smctr_status_chg(dev); | ||
2444 | smctr_enable_16bit(dev); | ||
2445 | break; | ||
2446 | |||
2447 | /* other interrupt types, illegal */ | ||
2448 | default: | ||
2449 | break; | ||
2450 | } | ||
2451 | |||
2452 | if(err != SUCCESS) | ||
2453 | break; | ||
2454 | } | ||
2455 | |||
2456 | /* Checking the ack code instead of the unmask bits here is because : | ||
2457 | * while fixing the stuck receive, DAT frame are sent and mask off | ||
2458 | * FIFO overrun interrupt temporarily (interrupt_unmask_bits = 0) | ||
2459 | * but we still want to issue ack to ISB | ||
2460 | */ | ||
2461 | if(!(interrupt_ack_code & 0xff00)) | ||
2462 | smctr_issue_int_ack(dev, interrupt_ack_code, interrupt_unmask_bits); | ||
2463 | |||
2464 | smctr_disable_16bit(dev); | ||
2465 | smctr_enable_bic_int(dev); | ||
2466 | spin_unlock(&tp->lock); | ||
2467 | |||
2468 | return IRQ_HANDLED; | ||
2469 | } | ||
2470 | |||
2471 | static int smctr_issue_enable_int_cmd(struct net_device *dev, | ||
2472 | __u16 interrupt_enable_mask) | ||
2473 | { | ||
2474 | struct net_local *tp = netdev_priv(dev); | ||
2475 | int err; | ||
2476 | |||
2477 | if((err = smctr_wait_while_cbusy(dev))) | ||
2478 | return (err); | ||
2479 | |||
2480 | tp->sclb_ptr->int_mask_control = interrupt_enable_mask; | ||
2481 | tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; | ||
2482 | |||
2483 | smctr_set_ctrl_attention(dev); | ||
2484 | |||
2485 | return (0); | ||
2486 | } | ||
2487 | |||
2488 | static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits) | ||
2489 | { | ||
2490 | struct net_local *tp = netdev_priv(dev); | ||
2491 | |||
2492 | if(smctr_wait_while_cbusy(dev)) | ||
2493 | return (-1); | ||
2494 | |||
2495 | tp->sclb_ptr->int_mask_control = ibits; | ||
2496 | tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0; | ||
2497 | tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_IACK_CODE_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; | ||
2498 | |||
2499 | smctr_set_ctrl_attention(dev); | ||
2500 | |||
2501 | return (0); | ||
2502 | } | ||
2503 | |||
2504 | static int smctr_issue_init_timers_cmd(struct net_device *dev) | ||
2505 | { | ||
2506 | struct net_local *tp = netdev_priv(dev); | ||
2507 | unsigned int i; | ||
2508 | int err; | ||
2509 | __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data; | ||
2510 | |||
2511 | if((err = smctr_wait_while_cbusy(dev))) | ||
2512 | return (err); | ||
2513 | |||
2514 | if((err = smctr_wait_cmd(dev))) | ||
2515 | return (err); | ||
2516 | |||
2517 | tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE; | ||
2518 | tp->config_word1 = 0; | ||
2519 | |||
2520 | if((tp->media_type == MEDIA_STP_16) | ||
2521 | || (tp->media_type == MEDIA_UTP_16) | ||
2522 | || (tp->media_type == MEDIA_STP_16_UTP_16)) | ||
2523 | { | ||
2524 | tp->config_word0 |= FREQ_16MB_BIT; | ||
2525 | } | ||
2526 | |||
2527 | if(tp->mode_bits & EARLY_TOKEN_REL) | ||
2528 | tp->config_word0 |= ETREN; | ||
2529 | |||
2530 | if(tp->mode_bits & LOOPING_MODE_MASK) | ||
2531 | tp->config_word0 |= RX_OWN_BIT; | ||
2532 | else | ||
2533 | tp->config_word0 &= ~RX_OWN_BIT; | ||
2534 | |||
2535 | if(tp->receive_mask & PROMISCUOUS_MODE) | ||
2536 | tp->config_word0 |= PROMISCUOUS_BIT; | ||
2537 | else | ||
2538 | tp->config_word0 &= ~PROMISCUOUS_BIT; | ||
2539 | |||
2540 | if(tp->receive_mask & ACCEPT_ERR_PACKETS) | ||
2541 | tp->config_word0 |= SAVBAD_BIT; | ||
2542 | else | ||
2543 | tp->config_word0 &= ~SAVBAD_BIT; | ||
2544 | |||
2545 | if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) | ||
2546 | tp->config_word0 |= RXATMAC; | ||
2547 | else | ||
2548 | tp->config_word0 &= ~RXATMAC; | ||
2549 | |||
2550 | if(tp->receive_mask & ACCEPT_MULTI_PROM) | ||
2551 | tp->config_word1 |= MULTICAST_ADDRESS_BIT; | ||
2552 | else | ||
2553 | tp->config_word1 &= ~MULTICAST_ADDRESS_BIT; | ||
2554 | |||
2555 | if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING) | ||
2556 | tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS; | ||
2557 | else | ||
2558 | { | ||
2559 | if(tp->receive_mask & ACCEPT_SOURCE_ROUTING) | ||
2560 | tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT; | ||
2561 | else | ||
2562 | tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS; | ||
2563 | } | ||
2564 | |||
2565 | if((tp->media_type == MEDIA_STP_16) | ||
2566 | || (tp->media_type == MEDIA_UTP_16) | ||
2567 | || (tp->media_type == MEDIA_STP_16_UTP_16)) | ||
2568 | { | ||
2569 | tp->config_word1 |= INTERFRAME_SPACING_16; | ||
2570 | } | ||
2571 | else | ||
2572 | tp->config_word1 |= INTERFRAME_SPACING_4; | ||
2573 | |||
2574 | *pTimer_Struc++ = tp->config_word0; | ||
2575 | *pTimer_Struc++ = tp->config_word1; | ||
2576 | |||
2577 | if((tp->media_type == MEDIA_STP_4) | ||
2578 | || (tp->media_type == MEDIA_UTP_4) | ||
2579 | || (tp->media_type == MEDIA_STP_4_UTP_4)) | ||
2580 | { | ||
2581 | *pTimer_Struc++ = 0x00FA; /* prescale */ | ||
2582 | *pTimer_Struc++ = 0x2710; /* TPT_limit */ | ||
2583 | *pTimer_Struc++ = 0x2710; /* TQP_limit */ | ||
2584 | *pTimer_Struc++ = 0x0A28; /* TNT_limit */ | ||
2585 | *pTimer_Struc++ = 0x3E80; /* TBT_limit */ | ||
2586 | *pTimer_Struc++ = 0x3A98; /* TSM_limit */ | ||
2587 | *pTimer_Struc++ = 0x1B58; /* TAM_limit */ | ||
2588 | *pTimer_Struc++ = 0x00C8; /* TBR_limit */ | ||
2589 | *pTimer_Struc++ = 0x07D0; /* TER_limit */ | ||
2590 | *pTimer_Struc++ = 0x000A; /* TGT_limit */ | ||
2591 | *pTimer_Struc++ = 0x1162; /* THT_limit */ | ||
2592 | *pTimer_Struc++ = 0x07D0; /* TRR_limit */ | ||
2593 | *pTimer_Struc++ = 0x1388; /* TVX_limit */ | ||
2594 | *pTimer_Struc++ = 0x0000; /* reserved */ | ||
2595 | } | ||
2596 | else | ||
2597 | { | ||
2598 | *pTimer_Struc++ = 0x03E8; /* prescale */ | ||
2599 | *pTimer_Struc++ = 0x9C40; /* TPT_limit */ | ||
2600 | *pTimer_Struc++ = 0x9C40; /* TQP_limit */ | ||
2601 | *pTimer_Struc++ = 0x0A28; /* TNT_limit */ | ||
2602 | *pTimer_Struc++ = 0x3E80; /* TBT_limit */ | ||
2603 | *pTimer_Struc++ = 0x3A98; /* TSM_limit */ | ||
2604 | *pTimer_Struc++ = 0x1B58; /* TAM_limit */ | ||
2605 | *pTimer_Struc++ = 0x00C8; /* TBR_limit */ | ||
2606 | *pTimer_Struc++ = 0x07D0; /* TER_limit */ | ||
2607 | *pTimer_Struc++ = 0x000A; /* TGT_limit */ | ||
2608 | *pTimer_Struc++ = 0x4588; /* THT_limit */ | ||
2609 | *pTimer_Struc++ = 0x1F40; /* TRR_limit */ | ||
2610 | *pTimer_Struc++ = 0x4E20; /* TVX_limit */ | ||
2611 | *pTimer_Struc++ = 0x0000; /* reserved */ | ||
2612 | } | ||
2613 | |||
2614 | /* Set node address. */ | ||
2615 | *pTimer_Struc++ = dev->dev_addr[0] << 8 | ||
2616 | | (dev->dev_addr[1] & 0xFF); | ||
2617 | *pTimer_Struc++ = dev->dev_addr[2] << 8 | ||
2618 | | (dev->dev_addr[3] & 0xFF); | ||
2619 | *pTimer_Struc++ = dev->dev_addr[4] << 8 | ||
2620 | | (dev->dev_addr[5] & 0xFF); | ||
2621 | |||
2622 | /* Set group address. */ | ||
2623 | *pTimer_Struc++ = tp->group_address_0 << 8 | ||
2624 | | tp->group_address_0 >> 8; | ||
2625 | *pTimer_Struc++ = tp->group_address[0] << 8 | ||
2626 | | tp->group_address[0] >> 8; | ||
2627 | *pTimer_Struc++ = tp->group_address[1] << 8 | ||
2628 | | tp->group_address[1] >> 8; | ||
2629 | |||
2630 | /* Set functional address. */ | ||
2631 | *pTimer_Struc++ = tp->functional_address_0 << 8 | ||
2632 | | tp->functional_address_0 >> 8; | ||
2633 | *pTimer_Struc++ = tp->functional_address[0] << 8 | ||
2634 | | tp->functional_address[0] >> 8; | ||
2635 | *pTimer_Struc++ = tp->functional_address[1] << 8 | ||
2636 | | tp->functional_address[1] >> 8; | ||
2637 | |||
2638 | /* Set Bit-Wise group address. */ | ||
2639 | *pTimer_Struc++ = tp->bitwise_group_address[0] << 8 | ||
2640 | | tp->bitwise_group_address[0] >> 8; | ||
2641 | *pTimer_Struc++ = tp->bitwise_group_address[1] << 8 | ||
2642 | | tp->bitwise_group_address[1] >> 8; | ||
2643 | |||
2644 | /* Set ring number address. */ | ||
2645 | *pTimer_Struc++ = tp->source_ring_number; | ||
2646 | *pTimer_Struc++ = tp->target_ring_number; | ||
2647 | |||
2648 | /* Physical drop number. */ | ||
2649 | *pTimer_Struc++ = (unsigned short)0; | ||
2650 | *pTimer_Struc++ = (unsigned short)0; | ||
2651 | |||
2652 | /* Product instance ID. */ | ||
2653 | for(i = 0; i < 9; i++) | ||
2654 | *pTimer_Struc++ = (unsigned short)0; | ||
2655 | |||
2656 | err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0); | ||
2657 | |||
2658 | return (err); | ||
2659 | } | ||
2660 | |||
2661 | static int smctr_issue_init_txrx_cmd(struct net_device *dev) | ||
2662 | { | ||
2663 | struct net_local *tp = netdev_priv(dev); | ||
2664 | unsigned int i; | ||
2665 | int err; | ||
2666 | void **txrx_ptrs = (void *)tp->misc_command_data; | ||
2667 | |||
2668 | if((err = smctr_wait_while_cbusy(dev))) | ||
2669 | return (err); | ||
2670 | |||
2671 | if((err = smctr_wait_cmd(dev))) | ||
2672 | { | ||
2673 | printk(KERN_ERR "%s: Hardware failure\n", dev->name); | ||
2674 | return (err); | ||
2675 | } | ||
2676 | |||
2677 | /* Initialize Transmit Queue Pointers that are used, to point to | ||
2678 | * a single FCB. | ||
2679 | */ | ||
2680 | for(i = 0; i < NUM_TX_QS_USED; i++) | ||
2681 | *txrx_ptrs++ = (void *)TRC_POINTER(tp->tx_fcb_head[i]); | ||
2682 | |||
2683 | /* Initialize Transmit Queue Pointers that are NOT used to ZERO. */ | ||
2684 | for(; i < MAX_TX_QS; i++) | ||
2685 | *txrx_ptrs++ = (void *)0; | ||
2686 | |||
2687 | /* Initialize Receive Queue Pointers (MAC and Non-MAC) that are | ||
2688 | * used, to point to a single FCB and a BDB chain of buffers. | ||
2689 | */ | ||
2690 | for(i = 0; i < NUM_RX_QS_USED; i++) | ||
2691 | { | ||
2692 | *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_fcb_head[i]); | ||
2693 | *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_bdb_head[i]); | ||
2694 | } | ||
2695 | |||
2696 | /* Initialize Receive Queue Pointers that are NOT used to ZERO. */ | ||
2697 | for(; i < MAX_RX_QS; i++) | ||
2698 | { | ||
2699 | *txrx_ptrs++ = (void *)0; | ||
2700 | *txrx_ptrs++ = (void *)0; | ||
2701 | } | ||
2702 | |||
2703 | err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0); | ||
2704 | |||
2705 | return (err); | ||
2706 | } | ||
2707 | |||
2708 | static int smctr_issue_insert_cmd(struct net_device *dev) | ||
2709 | { | ||
2710 | int err; | ||
2711 | |||
2712 | err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP); | ||
2713 | |||
2714 | return (err); | ||
2715 | } | ||
2716 | |||
2717 | static int smctr_issue_read_ring_status_cmd(struct net_device *dev) | ||
2718 | { | ||
2719 | int err; | ||
2720 | |||
2721 | if((err = smctr_wait_while_cbusy(dev))) | ||
2722 | return (err); | ||
2723 | |||
2724 | if((err = smctr_wait_cmd(dev))) | ||
2725 | return (err); | ||
2726 | |||
2727 | err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS, | ||
2728 | RW_TRC_STATUS_BLOCK); | ||
2729 | |||
2730 | return (err); | ||
2731 | } | ||
2732 | |||
2733 | static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt) | ||
2734 | { | ||
2735 | int err; | ||
2736 | |||
2737 | if((err = smctr_wait_while_cbusy(dev))) | ||
2738 | return (err); | ||
2739 | |||
2740 | if((err = smctr_wait_cmd(dev))) | ||
2741 | return (err); | ||
2742 | |||
2743 | err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE, | ||
2744 | aword_cnt); | ||
2745 | |||
2746 | return (err); | ||
2747 | } | ||
2748 | |||
2749 | static int smctr_issue_remove_cmd(struct net_device *dev) | ||
2750 | { | ||
2751 | struct net_local *tp = netdev_priv(dev); | ||
2752 | int err; | ||
2753 | |||
2754 | if((err = smctr_wait_while_cbusy(dev))) | ||
2755 | return (err); | ||
2756 | |||
2757 | tp->sclb_ptr->resume_control = 0; | ||
2758 | tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_REMOVE; | ||
2759 | |||
2760 | smctr_set_ctrl_attention(dev); | ||
2761 | |||
2762 | return (0); | ||
2763 | } | ||
2764 | |||
2765 | static int smctr_issue_resume_acb_cmd(struct net_device *dev) | ||
2766 | { | ||
2767 | struct net_local *tp = netdev_priv(dev); | ||
2768 | int err; | ||
2769 | |||
2770 | if((err = smctr_wait_while_cbusy(dev))) | ||
2771 | return (err); | ||
2772 | |||
2773 | tp->sclb_ptr->resume_control = SCLB_RC_ACB; | ||
2774 | tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; | ||
2775 | |||
2776 | tp->acb_pending = 1; | ||
2777 | |||
2778 | smctr_set_ctrl_attention(dev); | ||
2779 | |||
2780 | return (0); | ||
2781 | } | ||
2782 | |||
2783 | static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) | ||
2784 | { | ||
2785 | struct net_local *tp = netdev_priv(dev); | ||
2786 | int err; | ||
2787 | |||
2788 | if((err = smctr_wait_while_cbusy(dev))) | ||
2789 | return (err); | ||
2790 | |||
2791 | if(queue == MAC_QUEUE) | ||
2792 | tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB; | ||
2793 | else | ||
2794 | tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_BDB; | ||
2795 | |||
2796 | tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; | ||
2797 | |||
2798 | smctr_set_ctrl_attention(dev); | ||
2799 | |||
2800 | return (0); | ||
2801 | } | ||
2802 | |||
2803 | static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) | ||
2804 | { | ||
2805 | struct net_local *tp = netdev_priv(dev); | ||
2806 | |||
2807 | if(smctr_debug > 10) | ||
2808 | printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name); | ||
2809 | |||
2810 | if(smctr_wait_while_cbusy(dev)) | ||
2811 | return (-1); | ||
2812 | |||
2813 | if(queue == MAC_QUEUE) | ||
2814 | tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB; | ||
2815 | else | ||
2816 | tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_FCB; | ||
2817 | |||
2818 | tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; | ||
2819 | |||
2820 | smctr_set_ctrl_attention(dev); | ||
2821 | |||
2822 | return (0); | ||
2823 | } | ||
2824 | |||
2825 | static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) | ||
2826 | { | ||
2827 | struct net_local *tp = netdev_priv(dev); | ||
2828 | |||
2829 | if(smctr_debug > 10) | ||
2830 | printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name); | ||
2831 | |||
2832 | if(smctr_wait_while_cbusy(dev)) | ||
2833 | return (-1); | ||
2834 | |||
2835 | tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue); | ||
2836 | tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID; | ||
2837 | |||
2838 | smctr_set_ctrl_attention(dev); | ||
2839 | |||
2840 | return (0); | ||
2841 | } | ||
2842 | |||
2843 | static int smctr_issue_test_internal_rom_cmd(struct net_device *dev) | ||
2844 | { | ||
2845 | int err; | ||
2846 | |||
2847 | err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, | ||
2848 | TRC_INTERNAL_ROM_TEST); | ||
2849 | |||
2850 | return (err); | ||
2851 | } | ||
2852 | |||
2853 | static int smctr_issue_test_hic_cmd(struct net_device *dev) | ||
2854 | { | ||
2855 | int err; | ||
2856 | |||
2857 | err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST, | ||
2858 | TRC_HOST_INTERFACE_REG_TEST); | ||
2859 | |||
2860 | return (err); | ||
2861 | } | ||
2862 | |||
2863 | static int smctr_issue_test_mac_reg_cmd(struct net_device *dev) | ||
2864 | { | ||
2865 | int err; | ||
2866 | |||
2867 | err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, | ||
2868 | TRC_MAC_REGISTERS_TEST); | ||
2869 | |||
2870 | return (err); | ||
2871 | } | ||
2872 | |||
2873 | static int smctr_issue_trc_loopback_cmd(struct net_device *dev) | ||
2874 | { | ||
2875 | int err; | ||
2876 | |||
2877 | err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, | ||
2878 | TRC_INTERNAL_LOOPBACK); | ||
2879 | |||
2880 | return (err); | ||
2881 | } | ||
2882 | |||
2883 | static int smctr_issue_tri_loopback_cmd(struct net_device *dev) | ||
2884 | { | ||
2885 | int err; | ||
2886 | |||
2887 | err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, | ||
2888 | TRC_TRI_LOOPBACK); | ||
2889 | |||
2890 | return (err); | ||
2891 | } | ||
2892 | |||
2893 | static int smctr_issue_write_byte_cmd(struct net_device *dev, | ||
2894 | short aword_cnt, void *byte) | ||
2895 | { | ||
2896 | struct net_local *tp = netdev_priv(dev); | ||
2897 | unsigned int iword, ibyte; | ||
2898 | int err; | ||
2899 | |||
2900 | if((err = smctr_wait_while_cbusy(dev))) | ||
2901 | return (err); | ||
2902 | |||
2903 | if((err = smctr_wait_cmd(dev))) | ||
2904 | return (err); | ||
2905 | |||
2906 | for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff); | ||
2907 | iword++, ibyte += 2) | ||
2908 | { | ||
2909 | tp->misc_command_data[iword] = (*((__u8 *)byte + ibyte) << 8) | ||
2910 | | (*((__u8 *)byte + ibyte + 1)); | ||
2911 | } | ||
2912 | |||
2913 | return (smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, | ||
2914 | aword_cnt)); | ||
2915 | } | ||
2916 | |||
2917 | static int smctr_issue_write_word_cmd(struct net_device *dev, | ||
2918 | short aword_cnt, void *word) | ||
2919 | { | ||
2920 | struct net_local *tp = netdev_priv(dev); | ||
2921 | unsigned int i, err; | ||
2922 | |||
2923 | if((err = smctr_wait_while_cbusy(dev))) | ||
2924 | return (err); | ||
2925 | |||
2926 | if((err = smctr_wait_cmd(dev))) | ||
2927 | return (err); | ||
2928 | |||
2929 | for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++) | ||
2930 | tp->misc_command_data[i] = *((__u16 *)word + i); | ||
2931 | |||
2932 | err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, | ||
2933 | aword_cnt); | ||
2934 | |||
2935 | return (err); | ||
2936 | } | ||
2937 | |||
2938 | static int smctr_join_complete_state(struct net_device *dev) | ||
2939 | { | ||
2940 | int err; | ||
2941 | |||
2942 | err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, | ||
2943 | JS_JOIN_COMPLETE_STATE); | ||
2944 | |||
2945 | return (err); | ||
2946 | } | ||
2947 | |||
2948 | static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) | ||
2949 | { | ||
2950 | struct net_local *tp = netdev_priv(dev); | ||
2951 | unsigned int i, j; | ||
2952 | FCBlock *fcb; | ||
2953 | BDBlock *bdb; | ||
2954 | |||
2955 | for(i = 0; i < NUM_TX_QS_USED; i++) | ||
2956 | { | ||
2957 | fcb = tp->tx_fcb_head[i]; | ||
2958 | bdb = tp->tx_bdb_head[i]; | ||
2959 | |||
2960 | for(j = 0; j < tp->num_tx_fcbs[i]; j++) | ||
2961 | { | ||
2962 | fcb->bdb_ptr = bdb; | ||
2963 | fcb->trc_bdb_ptr = TRC_POINTER(bdb); | ||
2964 | fcb = (FCBlock *)((char *)fcb + sizeof(FCBlock)); | ||
2965 | bdb = (BDBlock *)((char *)bdb + sizeof(BDBlock)); | ||
2966 | } | ||
2967 | } | ||
2968 | |||
2969 | return (0); | ||
2970 | } | ||
2971 | |||
2972 | static int smctr_load_firmware(struct net_device *dev) | ||
2973 | { | ||
2974 | struct net_local *tp = netdev_priv(dev); | ||
2975 | __u16 i, checksum = 0; | ||
2976 | int err = 0; | ||
2977 | |||
2978 | if(smctr_debug > 10) | ||
2979 | printk(KERN_DEBUG "%s: smctr_load_firmware\n", dev->name); | ||
2980 | |||
2981 | tp->ptr_ucode = smctr_code; | ||
2982 | tp->num_of_tx_buffs = 4; | ||
2983 | tp->mode_bits |= UMAC; | ||
2984 | tp->receive_mask = 0; | ||
2985 | tp->max_packet_size = 4177; | ||
2986 | |||
2987 | /* Can only upload the firmware once per adapter reset. */ | ||
2988 | if(tp->microcode_version != 0) | ||
2989 | return (UCODE_PRESENT); | ||
2990 | |||
2991 | /* Verify the firmware exists and is there in the right amount. */ | ||
2992 | if((tp->ptr_ucode == 0L) | ||
2993 | || (*(tp->ptr_ucode + UCODE_VERSION_OFFSET) < UCODE_VERSION)) | ||
2994 | { | ||
2995 | return (UCODE_NOT_PRESENT); | ||
2996 | } | ||
2997 | |||
2998 | /* UCODE_SIZE is not included in Checksum. */ | ||
2999 | for(i = 0; i < *((__u16 *)(tp->ptr_ucode + UCODE_SIZE_OFFSET)); i += 2) | ||
3000 | checksum += *((__u16 *)(tp->ptr_ucode + 2 + i)); | ||
3001 | if(checksum) | ||
3002 | return (UCODE_NOT_PRESENT); | ||
3003 | |||
3004 | /* At this point we have a valid firmware image, lets kick it on up. */ | ||
3005 | smctr_enable_adapter_ram(dev); | ||
3006 | smctr_enable_16bit(dev); | ||
3007 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
3008 | |||
3009 | if((smctr_checksum_firmware(dev)) | ||
3010 | || (*(tp->ptr_ucode + UCODE_VERSION_OFFSET) | ||
3011 | > tp->microcode_version)) | ||
3012 | { | ||
3013 | smctr_enable_adapter_ctrl_store(dev); | ||
3014 | |||
3015 | /* Zero out ram space for firmware. */ | ||
3016 | for(i = 0; i < CS_RAM_SIZE; i += 2) | ||
3017 | *((__u16 *)(tp->ram_access + i)) = 0; | ||
3018 | |||
3019 | smctr_decode_firmware(dev); | ||
3020 | |||
3021 | tp->microcode_version = *(tp->ptr_ucode + UCODE_VERSION_OFFSET); *((__u16 *)(tp->ram_access + CS_RAM_VERSION_OFFSET)) | ||
3022 | = (tp->microcode_version << 8); | ||
3023 | *((__u16 *)(tp->ram_access + CS_RAM_CHECKSUM_OFFSET)) | ||
3024 | = ~(tp->microcode_version << 8) + 1; | ||
3025 | |||
3026 | smctr_disable_adapter_ctrl_store(dev); | ||
3027 | |||
3028 | if(smctr_checksum_firmware(dev)) | ||
3029 | err = HARDWARE_FAILED; | ||
3030 | } | ||
3031 | else | ||
3032 | err = UCODE_PRESENT; | ||
3033 | |||
3034 | smctr_disable_16bit(dev); | ||
3035 | |||
3036 | return (err); | ||
3037 | } | ||
3038 | |||
3039 | static int smctr_load_node_addr(struct net_device *dev) | ||
3040 | { | ||
3041 | int ioaddr = dev->base_addr; | ||
3042 | unsigned int i; | ||
3043 | __u8 r; | ||
3044 | |||
3045 | for(i = 0; i < 6; i++) | ||
3046 | { | ||
3047 | r = inb(ioaddr + LAR0 + i); | ||
3048 | dev->dev_addr[i] = (char)r; | ||
3049 | } | ||
3050 | dev->addr_len = 6; | ||
3051 | |||
3052 | return (0); | ||
3053 | } | ||
3054 | |||
3055 | /* Lobe Media Test. | ||
3056 | * During the transmission of the initial 1500 lobe media MAC frames, | ||
3057 | * the phase lock loop in the 805 chip may lock, and then un-lock, causing | ||
3058 | * the 825 to go into a PURGE state. When performing a PURGE, the MCT | ||
3059 | * microcode will not transmit any frames given to it by the host, and | ||
3060 | * will consequently cause a timeout. | ||
3061 | * | ||
3062 | * NOTE 1: If the monitor_state is MS_BEACON_TEST_STATE, all transmit | ||
3063 | * queues other then the one used for the lobe_media_test should be | ||
3064 | * disabled.!? | ||
3065 | * | ||
3066 | * NOTE 2: If the monitor_state is MS_BEACON_TEST_STATE and the receive_mask | ||
3067 | * has any multi-cast or promiscous bits set, the receive_mask needs to | ||
3068 | * be changed to clear the multi-cast or promiscous mode bits, the lobe_test | ||
3069 | * run, and then the receive mask set back to its original value if the test | ||
3070 | * is successful. | ||
3071 | */ | ||
3072 | static int smctr_lobe_media_test(struct net_device *dev) | ||
3073 | { | ||
3074 | struct net_local *tp = netdev_priv(dev); | ||
3075 | unsigned int i, perror = 0; | ||
3076 | unsigned short saved_rcv_mask; | ||
3077 | |||
3078 | if(smctr_debug > 10) | ||
3079 | printk(KERN_DEBUG "%s: smctr_lobe_media_test\n", dev->name); | ||
3080 | |||
3081 | /* Clear receive mask for lobe test. */ | ||
3082 | saved_rcv_mask = tp->receive_mask; | ||
3083 | tp->receive_mask = 0; | ||
3084 | |||
3085 | smctr_chg_rx_mask(dev); | ||
3086 | |||
3087 | /* Setup the lobe media test. */ | ||
3088 | smctr_lobe_media_test_cmd(dev); | ||
3089 | if(smctr_wait_cmd(dev)) | ||
3090 | { | ||
3091 | smctr_reset_adapter(dev); | ||
3092 | tp->status = CLOSED; | ||
3093 | return (LOBE_MEDIA_TEST_FAILED); | ||
3094 | } | ||
3095 | |||
3096 | /* Tx lobe media test frames. */ | ||
3097 | for(i = 0; i < 1500; ++i) | ||
3098 | { | ||
3099 | if(smctr_send_lobe_media_test(dev)) | ||
3100 | { | ||
3101 | if(perror) | ||
3102 | { | ||
3103 | smctr_reset_adapter(dev); | ||
3104 | tp->state = CLOSED; | ||
3105 | return (LOBE_MEDIA_TEST_FAILED); | ||
3106 | } | ||
3107 | else | ||
3108 | { | ||
3109 | perror = 1; | ||
3110 | if(smctr_lobe_media_test_cmd(dev)) | ||
3111 | { | ||
3112 | smctr_reset_adapter(dev); | ||
3113 | tp->state = CLOSED; | ||
3114 | return (LOBE_MEDIA_TEST_FAILED); | ||
3115 | } | ||
3116 | } | ||
3117 | } | ||
3118 | } | ||
3119 | |||
3120 | if(smctr_send_dat(dev)) | ||
3121 | { | ||
3122 | if(smctr_send_dat(dev)) | ||
3123 | { | ||
3124 | smctr_reset_adapter(dev); | ||
3125 | tp->state = CLOSED; | ||
3126 | return (LOBE_MEDIA_TEST_FAILED); | ||
3127 | } | ||
3128 | } | ||
3129 | |||
3130 | /* Check if any frames received during test. */ | ||
3131 | if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status) | ||
3132 | || (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status)) | ||
3133 | { | ||
3134 | smctr_reset_adapter(dev); | ||
3135 | tp->state = CLOSED; | ||
3136 | return (LOBE_MEDIA_TEST_FAILED); | ||
3137 | } | ||
3138 | |||
3139 | /* Set receive mask to "Promisc" mode. */ | ||
3140 | tp->receive_mask = saved_rcv_mask; | ||
3141 | |||
3142 | smctr_chg_rx_mask(dev); | ||
3143 | |||
3144 | return (0); | ||
3145 | } | ||
3146 | |||
3147 | static int smctr_lobe_media_test_cmd(struct net_device *dev) | ||
3148 | { | ||
3149 | struct net_local *tp = netdev_priv(dev); | ||
3150 | int err; | ||
3151 | |||
3152 | if(smctr_debug > 10) | ||
3153 | printk(KERN_DEBUG "%s: smctr_lobe_media_test_cmd\n", dev->name); | ||
3154 | |||
3155 | /* Change to lobe media test state. */ | ||
3156 | if(tp->monitor_state != MS_BEACON_TEST_STATE) | ||
3157 | { | ||
3158 | smctr_lobe_media_test_state(dev); | ||
3159 | if(smctr_wait_cmd(dev)) | ||
3160 | { | ||
3161 | printk(KERN_ERR "Lobe Failed test state\n"); | ||
3162 | return (LOBE_MEDIA_TEST_FAILED); | ||
3163 | } | ||
3164 | } | ||
3165 | |||
3166 | err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, | ||
3167 | TRC_LOBE_MEDIA_TEST); | ||
3168 | |||
3169 | return (err); | ||
3170 | } | ||
3171 | |||
3172 | static int smctr_lobe_media_test_state(struct net_device *dev) | ||
3173 | { | ||
3174 | int err; | ||
3175 | |||
3176 | err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, | ||
3177 | JS_LOBE_TEST_STATE); | ||
3178 | |||
3179 | return (err); | ||
3180 | } | ||
3181 | |||
3182 | static int smctr_make_8025_hdr(struct net_device *dev, | ||
3183 | MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc) | ||
3184 | { | ||
3185 | tmf->ac = MSB(ac_fc); /* msb is access control */ | ||
3186 | tmf->fc = LSB(ac_fc); /* lsb is frame control */ | ||
3187 | |||
3188 | tmf->sa[0] = dev->dev_addr[0]; | ||
3189 | tmf->sa[1] = dev->dev_addr[1]; | ||
3190 | tmf->sa[2] = dev->dev_addr[2]; | ||
3191 | tmf->sa[3] = dev->dev_addr[3]; | ||
3192 | tmf->sa[4] = dev->dev_addr[4]; | ||
3193 | tmf->sa[5] = dev->dev_addr[5]; | ||
3194 | |||
3195 | switch(tmf->vc) | ||
3196 | { | ||
3197 | /* Send RQ_INIT to RPS */ | ||
3198 | case RQ_INIT: | ||
3199 | tmf->da[0] = 0xc0; | ||
3200 | tmf->da[1] = 0x00; | ||
3201 | tmf->da[2] = 0x00; | ||
3202 | tmf->da[3] = 0x00; | ||
3203 | tmf->da[4] = 0x00; | ||
3204 | tmf->da[5] = 0x02; | ||
3205 | break; | ||
3206 | |||
3207 | /* Send RPT_TX_FORWARD to CRS */ | ||
3208 | case RPT_TX_FORWARD: | ||
3209 | tmf->da[0] = 0xc0; | ||
3210 | tmf->da[1] = 0x00; | ||
3211 | tmf->da[2] = 0x00; | ||
3212 | tmf->da[3] = 0x00; | ||
3213 | tmf->da[4] = 0x00; | ||
3214 | tmf->da[5] = 0x10; | ||
3215 | break; | ||
3216 | |||
3217 | /* Everything else goes to sender */ | ||
3218 | default: | ||
3219 | tmf->da[0] = rmf->sa[0]; | ||
3220 | tmf->da[1] = rmf->sa[1]; | ||
3221 | tmf->da[2] = rmf->sa[2]; | ||
3222 | tmf->da[3] = rmf->sa[3]; | ||
3223 | tmf->da[4] = rmf->sa[4]; | ||
3224 | tmf->da[5] = rmf->sa[5]; | ||
3225 | break; | ||
3226 | } | ||
3227 | |||
3228 | return (0); | ||
3229 | } | ||
3230 | |||
3231 | static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) | ||
3232 | { | ||
3233 | struct net_local *tp = netdev_priv(dev); | ||
3234 | |||
3235 | tsv->svi = AUTHORIZED_ACCESS_PRIORITY; | ||
3236 | tsv->svl = S_AUTHORIZED_ACCESS_PRIORITY; | ||
3237 | |||
3238 | tsv->svv[0] = MSB(tp->authorized_access_priority); | ||
3239 | tsv->svv[1] = LSB(tp->authorized_access_priority); | ||
3240 | |||
3241 | return (0); | ||
3242 | } | ||
3243 | |||
3244 | static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv) | ||
3245 | { | ||
3246 | tsv->svi = ADDRESS_MODIFER; | ||
3247 | tsv->svl = S_ADDRESS_MODIFER; | ||
3248 | |||
3249 | tsv->svv[0] = 0; | ||
3250 | tsv->svv[1] = 0; | ||
3251 | |||
3252 | return (0); | ||
3253 | } | ||
3254 | |||
3255 | static int smctr_make_auth_funct_class(struct net_device *dev, | ||
3256 | MAC_SUB_VECTOR *tsv) | ||
3257 | { | ||
3258 | struct net_local *tp = netdev_priv(dev); | ||
3259 | |||
3260 | tsv->svi = AUTHORIZED_FUNCTION_CLASS; | ||
3261 | tsv->svl = S_AUTHORIZED_FUNCTION_CLASS; | ||
3262 | |||
3263 | tsv->svv[0] = MSB(tp->authorized_function_classes); | ||
3264 | tsv->svv[1] = LSB(tp->authorized_function_classes); | ||
3265 | |||
3266 | return (0); | ||
3267 | } | ||
3268 | |||
3269 | static int smctr_make_corr(struct net_device *dev, | ||
3270 | MAC_SUB_VECTOR *tsv, __u16 correlator) | ||
3271 | { | ||
3272 | tsv->svi = CORRELATOR; | ||
3273 | tsv->svl = S_CORRELATOR; | ||
3274 | |||
3275 | tsv->svv[0] = MSB(correlator); | ||
3276 | tsv->svv[1] = LSB(correlator); | ||
3277 | |||
3278 | return (0); | ||
3279 | } | ||
3280 | |||
3281 | static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) | ||
3282 | { | ||
3283 | struct net_local *tp = netdev_priv(dev); | ||
3284 | |||
3285 | smctr_get_functional_address(dev); | ||
3286 | |||
3287 | tsv->svi = FUNCTIONAL_ADDRESS; | ||
3288 | tsv->svl = S_FUNCTIONAL_ADDRESS; | ||
3289 | |||
3290 | tsv->svv[0] = MSB(tp->misc_command_data[0]); | ||
3291 | tsv->svv[1] = LSB(tp->misc_command_data[0]); | ||
3292 | |||
3293 | tsv->svv[2] = MSB(tp->misc_command_data[1]); | ||
3294 | tsv->svv[3] = LSB(tp->misc_command_data[1]); | ||
3295 | |||
3296 | return (0); | ||
3297 | } | ||
3298 | |||
3299 | static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) | ||
3300 | { | ||
3301 | struct net_local *tp = netdev_priv(dev); | ||
3302 | |||
3303 | smctr_get_group_address(dev); | ||
3304 | |||
3305 | tsv->svi = GROUP_ADDRESS; | ||
3306 | tsv->svl = S_GROUP_ADDRESS; | ||
3307 | |||
3308 | tsv->svv[0] = MSB(tp->misc_command_data[0]); | ||
3309 | tsv->svv[1] = LSB(tp->misc_command_data[0]); | ||
3310 | |||
3311 | tsv->svv[2] = MSB(tp->misc_command_data[1]); | ||
3312 | tsv->svv[3] = LSB(tp->misc_command_data[1]); | ||
3313 | |||
3314 | /* Set Group Address Sub-vector to all zeros if only the | ||
3315 | * Group Address/Functional Address Indicator is set. | ||
3316 | */ | ||
3317 | if(tsv->svv[0] == 0x80 && tsv->svv[1] == 0x00 | ||
3318 | && tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00) | ||
3319 | tsv->svv[0] = 0x00; | ||
3320 | |||
3321 | return (0); | ||
3322 | } | ||
3323 | |||
3324 | static int smctr_make_phy_drop_num(struct net_device *dev, | ||
3325 | MAC_SUB_VECTOR *tsv) | ||
3326 | { | ||
3327 | struct net_local *tp = netdev_priv(dev); | ||
3328 | |||
3329 | smctr_get_physical_drop_number(dev); | ||
3330 | |||
3331 | tsv->svi = PHYSICAL_DROP; | ||
3332 | tsv->svl = S_PHYSICAL_DROP; | ||
3333 | |||
3334 | tsv->svv[0] = MSB(tp->misc_command_data[0]); | ||
3335 | tsv->svv[1] = LSB(tp->misc_command_data[0]); | ||
3336 | |||
3337 | tsv->svv[2] = MSB(tp->misc_command_data[1]); | ||
3338 | tsv->svv[3] = LSB(tp->misc_command_data[1]); | ||
3339 | |||
3340 | return (0); | ||
3341 | } | ||
3342 | |||
3343 | static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) | ||
3344 | { | ||
3345 | int i; | ||
3346 | |||
3347 | tsv->svi = PRODUCT_INSTANCE_ID; | ||
3348 | tsv->svl = S_PRODUCT_INSTANCE_ID; | ||
3349 | |||
3350 | for(i = 0; i < 18; i++) | ||
3351 | tsv->svv[i] = 0xF0; | ||
3352 | |||
3353 | return (0); | ||
3354 | } | ||
3355 | |||
3356 | static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) | ||
3357 | { | ||
3358 | struct net_local *tp = netdev_priv(dev); | ||
3359 | |||
3360 | smctr_get_station_id(dev); | ||
3361 | |||
3362 | tsv->svi = STATION_IDENTIFER; | ||
3363 | tsv->svl = S_STATION_IDENTIFER; | ||
3364 | |||
3365 | tsv->svv[0] = MSB(tp->misc_command_data[0]); | ||
3366 | tsv->svv[1] = LSB(tp->misc_command_data[0]); | ||
3367 | |||
3368 | tsv->svv[2] = MSB(tp->misc_command_data[1]); | ||
3369 | tsv->svv[3] = LSB(tp->misc_command_data[1]); | ||
3370 | |||
3371 | tsv->svv[4] = MSB(tp->misc_command_data[2]); | ||
3372 | tsv->svv[5] = LSB(tp->misc_command_data[2]); | ||
3373 | |||
3374 | return (0); | ||
3375 | } | ||
3376 | |||
3377 | static int smctr_make_ring_station_status(struct net_device *dev, | ||
3378 | MAC_SUB_VECTOR * tsv) | ||
3379 | { | ||
3380 | tsv->svi = RING_STATION_STATUS; | ||
3381 | tsv->svl = S_RING_STATION_STATUS; | ||
3382 | |||
3383 | tsv->svv[0] = 0; | ||
3384 | tsv->svv[1] = 0; | ||
3385 | tsv->svv[2] = 0; | ||
3386 | tsv->svv[3] = 0; | ||
3387 | tsv->svv[4] = 0; | ||
3388 | tsv->svv[5] = 0; | ||
3389 | |||
3390 | return (0); | ||
3391 | } | ||
3392 | |||
3393 | static int smctr_make_ring_station_version(struct net_device *dev, | ||
3394 | MAC_SUB_VECTOR *tsv) | ||
3395 | { | ||
3396 | struct net_local *tp = netdev_priv(dev); | ||
3397 | |||
3398 | tsv->svi = RING_STATION_VERSION_NUMBER; | ||
3399 | tsv->svl = S_RING_STATION_VERSION_NUMBER; | ||
3400 | |||
3401 | tsv->svv[0] = 0xe2; /* EBCDIC - S */ | ||
3402 | tsv->svv[1] = 0xd4; /* EBCDIC - M */ | ||
3403 | tsv->svv[2] = 0xc3; /* EBCDIC - C */ | ||
3404 | tsv->svv[3] = 0x40; /* EBCDIC - */ | ||
3405 | tsv->svv[4] = 0xe5; /* EBCDIC - V */ | ||
3406 | tsv->svv[5] = 0xF0 + (tp->microcode_version >> 4); | ||
3407 | tsv->svv[6] = 0xF0 + (tp->microcode_version & 0x0f); | ||
3408 | tsv->svv[7] = 0x40; /* EBCDIC - */ | ||
3409 | tsv->svv[8] = 0xe7; /* EBCDIC - X */ | ||
3410 | |||
3411 | if(tp->extra_info & CHIP_REV_MASK) | ||
3412 | tsv->svv[9] = 0xc5; /* EBCDIC - E */ | ||
3413 | else | ||
3414 | tsv->svv[9] = 0xc4; /* EBCDIC - D */ | ||
3415 | |||
3416 | return (0); | ||
3417 | } | ||
3418 | |||
3419 | static int smctr_make_tx_status_code(struct net_device *dev, | ||
3420 | MAC_SUB_VECTOR *tsv, __u16 tx_fstatus) | ||
3421 | { | ||
3422 | tsv->svi = TRANSMIT_STATUS_CODE; | ||
3423 | tsv->svl = S_TRANSMIT_STATUS_CODE; | ||
3424 | |||
3425 | tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) || IBM_PASS_SOURCE_ADDR); | ||
3426 | |||
3427 | /* Stripped frame status of Transmitted Frame */ | ||
3428 | tsv->svv[1] = tx_fstatus & 0xff; | ||
3429 | |||
3430 | return (0); | ||
3431 | } | ||
3432 | |||
3433 | static int smctr_make_upstream_neighbor_addr(struct net_device *dev, | ||
3434 | MAC_SUB_VECTOR *tsv) | ||
3435 | { | ||
3436 | struct net_local *tp = netdev_priv(dev); | ||
3437 | |||
3438 | smctr_get_upstream_neighbor_addr(dev); | ||
3439 | |||
3440 | tsv->svi = UPSTREAM_NEIGHBOR_ADDRESS; | ||
3441 | tsv->svl = S_UPSTREAM_NEIGHBOR_ADDRESS; | ||
3442 | |||
3443 | tsv->svv[0] = MSB(tp->misc_command_data[0]); | ||
3444 | tsv->svv[1] = LSB(tp->misc_command_data[0]); | ||
3445 | |||
3446 | tsv->svv[2] = MSB(tp->misc_command_data[1]); | ||
3447 | tsv->svv[3] = LSB(tp->misc_command_data[1]); | ||
3448 | |||
3449 | tsv->svv[4] = MSB(tp->misc_command_data[2]); | ||
3450 | tsv->svv[5] = LSB(tp->misc_command_data[2]); | ||
3451 | |||
3452 | return (0); | ||
3453 | } | ||
3454 | |||
3455 | static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv) | ||
3456 | { | ||
3457 | tsv->svi = WRAP_DATA; | ||
3458 | tsv->svl = S_WRAP_DATA; | ||
3459 | |||
3460 | return (0); | ||
3461 | } | ||
3462 | |||
3463 | /* | ||
3464 | * Open/initialize the board. This is called sometime after | ||
3465 | * booting when the 'ifconfig' program is run. | ||
3466 | * | ||
3467 | * This routine should set everything up anew at each open, even | ||
3468 | * registers that "should" only need to be set once at boot, so that | ||
3469 | * there is non-reboot way to recover if something goes wrong. | ||
3470 | */ | ||
3471 | static int smctr_open(struct net_device *dev) | ||
3472 | { | ||
3473 | int err; | ||
3474 | |||
3475 | if(smctr_debug > 10) | ||
3476 | printk(KERN_DEBUG "%s: smctr_open\n", dev->name); | ||
3477 | |||
3478 | err = smctr_init_adapter(dev); | ||
3479 | if(err < 0) | ||
3480 | return (err); | ||
3481 | |||
3482 | return (err); | ||
3483 | } | ||
3484 | |||
3485 | /* Interrupt driven open of Token card. */ | ||
3486 | static int smctr_open_tr(struct net_device *dev) | ||
3487 | { | ||
3488 | struct net_local *tp = netdev_priv(dev); | ||
3489 | unsigned long flags; | ||
3490 | int err; | ||
3491 | |||
3492 | if(smctr_debug > 10) | ||
3493 | printk(KERN_DEBUG "%s: smctr_open_tr\n", dev->name); | ||
3494 | |||
3495 | /* Now we can actually open the adapter. */ | ||
3496 | if(tp->status == OPEN) | ||
3497 | return (0); | ||
3498 | if(tp->status != INITIALIZED) | ||
3499 | return (-1); | ||
3500 | |||
3501 | /* FIXME: it would work a lot better if we masked the irq sources | ||
3502 | on the card here, then we could skip the locking and poll nicely */ | ||
3503 | spin_lock_irqsave(&tp->lock, flags); | ||
3504 | |||
3505 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
3506 | |||
3507 | if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)MAC_QUEUE))) | ||
3508 | goto out; | ||
3509 | |||
3510 | if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)MAC_QUEUE))) | ||
3511 | goto out; | ||
3512 | |||
3513 | if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)NON_MAC_QUEUE))) | ||
3514 | goto out; | ||
3515 | |||
3516 | if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)NON_MAC_QUEUE))) | ||
3517 | goto out; | ||
3518 | |||
3519 | tp->status = CLOSED; | ||
3520 | |||
3521 | /* Insert into the Ring or Enter Loopback Mode. */ | ||
3522 | if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_1) | ||
3523 | { | ||
3524 | tp->status = CLOSED; | ||
3525 | |||
3526 | if(!(err = smctr_issue_trc_loopback_cmd(dev))) | ||
3527 | { | ||
3528 | if(!(err = smctr_wait_cmd(dev))) | ||
3529 | tp->status = OPEN; | ||
3530 | } | ||
3531 | |||
3532 | smctr_status_chg(dev); | ||
3533 | } | ||
3534 | else | ||
3535 | { | ||
3536 | if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_2) | ||
3537 | { | ||
3538 | tp->status = CLOSED; | ||
3539 | if(!(err = smctr_issue_tri_loopback_cmd(dev))) | ||
3540 | { | ||
3541 | if(!(err = smctr_wait_cmd(dev))) | ||
3542 | tp->status = OPEN; | ||
3543 | } | ||
3544 | |||
3545 | smctr_status_chg(dev); | ||
3546 | } | ||
3547 | else | ||
3548 | { | ||
3549 | if((tp->mode_bits & LOOPING_MODE_MASK) | ||
3550 | == LOOPBACK_MODE_3) | ||
3551 | { | ||
3552 | tp->status = CLOSED; | ||
3553 | if(!(err = smctr_lobe_media_test_cmd(dev))) | ||
3554 | { | ||
3555 | if(!(err = smctr_wait_cmd(dev))) | ||
3556 | tp->status = OPEN; | ||
3557 | } | ||
3558 | smctr_status_chg(dev); | ||
3559 | } | ||
3560 | else | ||
3561 | { | ||
3562 | if(!(err = smctr_lobe_media_test(dev))) | ||
3563 | err = smctr_issue_insert_cmd(dev); | ||
3564 | else | ||
3565 | { | ||
3566 | if(err == LOBE_MEDIA_TEST_FAILED) | ||
3567 | printk(KERN_WARNING "%s: Lobe Media Test Failure - Check cable?\n", dev->name); | ||
3568 | } | ||
3569 | } | ||
3570 | } | ||
3571 | } | ||
3572 | |||
3573 | out: | ||
3574 | spin_unlock_irqrestore(&tp->lock, flags); | ||
3575 | |||
3576 | return (err); | ||
3577 | } | ||
3578 | |||
3579 | /* Check for a network adapter of this type, | ||
3580 | * and return device structure if one exists. | ||
3581 | */ | ||
3582 | struct net_device __init *smctr_probe(int unit) | ||
3583 | { | ||
3584 | struct net_device *dev = alloc_trdev(sizeof(struct net_local)); | ||
3585 | static const unsigned ports[] = { | ||
3586 | 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, | ||
3587 | 0x320, 0x340, 0x360, 0x380, 0 | ||
3588 | }; | ||
3589 | const unsigned *port; | ||
3590 | int err = 0; | ||
3591 | |||
3592 | if (!dev) | ||
3593 | return ERR_PTR(-ENOMEM); | ||
3594 | |||
3595 | SET_MODULE_OWNER(dev); | ||
3596 | |||
3597 | if (unit >= 0) { | ||
3598 | sprintf(dev->name, "tr%d", unit); | ||
3599 | netdev_boot_setup_check(dev); | ||
3600 | } | ||
3601 | |||
3602 | if (dev->base_addr > 0x1ff) /* Check a single specified location. */ | ||
3603 | err = smctr_probe1(dev, dev->base_addr); | ||
3604 | else if(dev->base_addr != 0) /* Don't probe at all. */ | ||
3605 | err =-ENXIO; | ||
3606 | else { | ||
3607 | for (port = ports; *port; port++) { | ||
3608 | err = smctr_probe1(dev, *port); | ||
3609 | if (!err) | ||
3610 | break; | ||
3611 | } | ||
3612 | } | ||
3613 | if (err) | ||
3614 | goto out; | ||
3615 | err = register_netdev(dev); | ||
3616 | if (err) | ||
3617 | goto out1; | ||
3618 | return dev; | ||
3619 | out1: | ||
3620 | #ifdef CONFIG_MCA_LEGACY | ||
3621 | { struct net_local *tp = netdev_priv(dev); | ||
3622 | if (tp->slot_num) | ||
3623 | mca_mark_as_unused(tp->slot_num); | ||
3624 | } | ||
3625 | #endif | ||
3626 | release_region(dev->base_addr, SMCTR_IO_EXTENT); | ||
3627 | free_irq(dev->irq, dev); | ||
3628 | out: | ||
3629 | free_netdev(dev); | ||
3630 | return ERR_PTR(err); | ||
3631 | } | ||
3632 | |||
3633 | |||
3634 | static int __init smctr_probe1(struct net_device *dev, int ioaddr) | ||
3635 | { | ||
3636 | static unsigned version_printed; | ||
3637 | struct net_local *tp = netdev_priv(dev); | ||
3638 | int err; | ||
3639 | __u32 *ram; | ||
3640 | |||
3641 | if(smctr_debug && version_printed++ == 0) | ||
3642 | printk(version); | ||
3643 | |||
3644 | spin_lock_init(&tp->lock); | ||
3645 | dev->base_addr = ioaddr; | ||
3646 | |||
3647 | /* Actually detect an adapter now. */ | ||
3648 | err = smctr_chk_isa(dev); | ||
3649 | if(err < 0) | ||
3650 | { | ||
3651 | if ((err = smctr_chk_mca(dev)) < 0) { | ||
3652 | err = -ENODEV; | ||
3653 | goto out; | ||
3654 | } | ||
3655 | } | ||
3656 | |||
3657 | tp = netdev_priv(dev); | ||
3658 | dev->mem_start = tp->ram_base; | ||
3659 | dev->mem_end = dev->mem_start + 0x10000; | ||
3660 | ram = (__u32 *)phys_to_virt(dev->mem_start); | ||
3661 | tp->ram_access = *(__u32 *)&ram; | ||
3662 | tp->status = NOT_INITIALIZED; | ||
3663 | |||
3664 | err = smctr_load_firmware(dev); | ||
3665 | if(err != UCODE_PRESENT && err != SUCCESS) | ||
3666 | { | ||
3667 | printk(KERN_ERR "%s: Firmware load failed (%d)\n", dev->name, err); | ||
3668 | err = -EIO; | ||
3669 | goto out; | ||
3670 | } | ||
3671 | |||
3672 | /* Allow user to specify ring speed on module insert. */ | ||
3673 | if(ringspeed == 4) | ||
3674 | tp->media_type = MEDIA_UTP_4; | ||
3675 | else | ||
3676 | tp->media_type = MEDIA_UTP_16; | ||
3677 | |||
3678 | printk(KERN_INFO "%s: %s %s at Io %#4x, Irq %d, Rom %#4x, Ram %#4x.\n", | ||
3679 | dev->name, smctr_name, smctr_model, | ||
3680 | (unsigned int)dev->base_addr, | ||
3681 | dev->irq, tp->rom_base, tp->ram_base); | ||
3682 | |||
3683 | dev->open = smctr_open; | ||
3684 | dev->stop = smctr_close; | ||
3685 | dev->hard_start_xmit = smctr_send_packet; | ||
3686 | dev->tx_timeout = smctr_timeout; | ||
3687 | dev->watchdog_timeo = HZ; | ||
3688 | dev->get_stats = smctr_get_stats; | ||
3689 | dev->set_multicast_list = &smctr_set_multicast_list; | ||
3690 | return (0); | ||
3691 | |||
3692 | out: | ||
3693 | return err; | ||
3694 | } | ||
3695 | |||
3696 | static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, | ||
3697 | struct net_device *dev, __u16 rx_status) | ||
3698 | { | ||
3699 | struct net_local *tp = netdev_priv(dev); | ||
3700 | struct sk_buff *skb; | ||
3701 | __u16 rcode, correlator; | ||
3702 | int err = 0; | ||
3703 | __u8 xframe = 1; | ||
3704 | __u16 tx_fstatus; | ||
3705 | |||
3706 | rmf->vl = SWAP_BYTES(rmf->vl); | ||
3707 | if(rx_status & FCB_RX_STATUS_DA_MATCHED) | ||
3708 | { | ||
3709 | switch(rmf->vc) | ||
3710 | { | ||
3711 | /* Received MAC Frames Processed by RS. */ | ||
3712 | case INIT: | ||
3713 | if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED) | ||
3714 | { | ||
3715 | return (rcode); | ||
3716 | } | ||
3717 | |||
3718 | if((err = smctr_send_rsp(dev, rmf, rcode, | ||
3719 | correlator))) | ||
3720 | { | ||
3721 | return (err); | ||
3722 | } | ||
3723 | break; | ||
3724 | |||
3725 | case CHG_PARM: | ||
3726 | if((rcode = smctr_rcv_chg_param(dev, rmf, | ||
3727 | &correlator)) ==HARDWARE_FAILED) | ||
3728 | { | ||
3729 | return (rcode); | ||
3730 | } | ||
3731 | |||
3732 | if((err = smctr_send_rsp(dev, rmf, rcode, | ||
3733 | correlator))) | ||
3734 | { | ||
3735 | return (err); | ||
3736 | } | ||
3737 | break; | ||
3738 | |||
3739 | case RQ_ADDR: | ||
3740 | if((rcode = smctr_rcv_rq_addr_state_attch(dev, | ||
3741 | rmf, &correlator)) != POSITIVE_ACK) | ||
3742 | { | ||
3743 | if(rcode == HARDWARE_FAILED) | ||
3744 | return (rcode); | ||
3745 | else | ||
3746 | return (smctr_send_rsp(dev, rmf, | ||
3747 | rcode, correlator)); | ||
3748 | } | ||
3749 | |||
3750 | if((err = smctr_send_rpt_addr(dev, rmf, | ||
3751 | correlator))) | ||
3752 | { | ||
3753 | return (err); | ||
3754 | } | ||
3755 | break; | ||
3756 | |||
3757 | case RQ_ATTCH: | ||
3758 | if((rcode = smctr_rcv_rq_addr_state_attch(dev, | ||
3759 | rmf, &correlator)) != POSITIVE_ACK) | ||
3760 | { | ||
3761 | if(rcode == HARDWARE_FAILED) | ||
3762 | return (rcode); | ||
3763 | else | ||
3764 | return (smctr_send_rsp(dev, rmf, | ||
3765 | rcode, | ||
3766 | correlator)); | ||
3767 | } | ||
3768 | |||
3769 | if((err = smctr_send_rpt_attch(dev, rmf, | ||
3770 | correlator))) | ||
3771 | { | ||
3772 | return (err); | ||
3773 | } | ||
3774 | break; | ||
3775 | |||
3776 | case RQ_STATE: | ||
3777 | if((rcode = smctr_rcv_rq_addr_state_attch(dev, | ||
3778 | rmf, &correlator)) != POSITIVE_ACK) | ||
3779 | { | ||
3780 | if(rcode == HARDWARE_FAILED) | ||
3781 | return (rcode); | ||
3782 | else | ||
3783 | return (smctr_send_rsp(dev, rmf, | ||
3784 | rcode, | ||
3785 | correlator)); | ||
3786 | } | ||
3787 | |||
3788 | if((err = smctr_send_rpt_state(dev, rmf, | ||
3789 | correlator))) | ||
3790 | { | ||
3791 | return (err); | ||
3792 | } | ||
3793 | break; | ||
3794 | |||
3795 | case TX_FORWARD: | ||
3796 | if((rcode = smctr_rcv_tx_forward(dev, rmf)) | ||
3797 | != POSITIVE_ACK) | ||
3798 | { | ||
3799 | if(rcode == HARDWARE_FAILED) | ||
3800 | return (rcode); | ||
3801 | else | ||
3802 | return (smctr_send_rsp(dev, rmf, | ||
3803 | rcode, | ||
3804 | correlator)); | ||
3805 | } | ||
3806 | |||
3807 | if((err = smctr_send_tx_forward(dev, rmf, | ||
3808 | &tx_fstatus)) == HARDWARE_FAILED) | ||
3809 | { | ||
3810 | return (err); | ||
3811 | } | ||
3812 | |||
3813 | if(err == A_FRAME_WAS_FORWARDED) | ||
3814 | { | ||
3815 | if((err = smctr_send_rpt_tx_forward(dev, | ||
3816 | rmf, tx_fstatus)) | ||
3817 | == HARDWARE_FAILED) | ||
3818 | { | ||
3819 | return (err); | ||
3820 | } | ||
3821 | } | ||
3822 | break; | ||
3823 | |||
3824 | /* Received MAC Frames Processed by CRS/REM/RPS. */ | ||
3825 | case RSP: | ||
3826 | case RQ_INIT: | ||
3827 | case RPT_NEW_MON: | ||
3828 | case RPT_SUA_CHG: | ||
3829 | case RPT_ACTIVE_ERR: | ||
3830 | case RPT_NN_INCMP: | ||
3831 | case RPT_ERROR: | ||
3832 | case RPT_ATTCH: | ||
3833 | case RPT_STATE: | ||
3834 | case RPT_ADDR: | ||
3835 | break; | ||
3836 | |||
3837 | /* Rcvd Att. MAC Frame (if RXATMAC set) or UNKNOWN */ | ||
3838 | default: | ||
3839 | xframe = 0; | ||
3840 | if(!(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)) | ||
3841 | { | ||
3842 | rcode = smctr_rcv_unknown(dev, rmf, | ||
3843 | &correlator); | ||
3844 | if((err = smctr_send_rsp(dev, rmf,rcode, | ||
3845 | correlator))) | ||
3846 | { | ||
3847 | return (err); | ||
3848 | } | ||
3849 | } | ||
3850 | |||
3851 | break; | ||
3852 | } | ||
3853 | } | ||
3854 | else | ||
3855 | { | ||
3856 | /* 1. DA doesn't match (Promiscuous Mode). | ||
3857 | * 2. Parse for Extended MAC Frame Type. | ||
3858 | */ | ||
3859 | switch(rmf->vc) | ||
3860 | { | ||
3861 | case RSP: | ||
3862 | case INIT: | ||
3863 | case RQ_INIT: | ||
3864 | case RQ_ADDR: | ||
3865 | case RQ_ATTCH: | ||
3866 | case RQ_STATE: | ||
3867 | case CHG_PARM: | ||
3868 | case RPT_ADDR: | ||
3869 | case RPT_ERROR: | ||
3870 | case RPT_ATTCH: | ||
3871 | case RPT_STATE: | ||
3872 | case RPT_NEW_MON: | ||
3873 | case RPT_SUA_CHG: | ||
3874 | case RPT_NN_INCMP: | ||
3875 | case RPT_ACTIVE_ERR: | ||
3876 | break; | ||
3877 | |||
3878 | default: | ||
3879 | xframe = 0; | ||
3880 | break; | ||
3881 | } | ||
3882 | } | ||
3883 | |||
3884 | /* NOTE: UNKNOWN MAC frames will NOT be passed up unless | ||
3885 | * ACCEPT_ATT_MAC_FRAMES is set. | ||
3886 | */ | ||
3887 | if(((tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) | ||
3888 | && (xframe == (__u8)0)) | ||
3889 | || ((tp->receive_mask & ACCEPT_EXT_MAC_FRAMES) | ||
3890 | && (xframe == (__u8)1))) | ||
3891 | { | ||
3892 | rmf->vl = SWAP_BYTES(rmf->vl); | ||
3893 | |||
3894 | if (!(skb = dev_alloc_skb(size))) | ||
3895 | return -ENOMEM; | ||
3896 | skb->len = size; | ||
3897 | |||
3898 | /* Slide data into a sleek skb. */ | ||
3899 | skb_put(skb, skb->len); | ||
3900 | memcpy(skb->data, rmf, skb->len); | ||
3901 | |||
3902 | /* Update Counters */ | ||
3903 | tp->MacStat.rx_packets++; | ||
3904 | tp->MacStat.rx_bytes += skb->len; | ||
3905 | |||
3906 | /* Kick the packet on up. */ | ||
3907 | skb->dev = dev; | ||
3908 | skb->protocol = tr_type_trans(skb, dev); | ||
3909 | netif_rx(skb); | ||
3910 | dev->last_rx = jiffies; | ||
3911 | err = 0; | ||
3912 | } | ||
3913 | |||
3914 | return (err); | ||
3915 | } | ||
3916 | |||
3917 | /* Adapter RAM test. Incremental word ODD boundary data test. */ | ||
3918 | static int smctr_ram_memory_test(struct net_device *dev) | ||
3919 | { | ||
3920 | struct net_local *tp = netdev_priv(dev); | ||
3921 | __u16 page, pages_of_ram, start_pattern = 0, word_pattern = 0, | ||
3922 | word_read = 0, err_word = 0, err_pattern = 0; | ||
3923 | unsigned int err_offset; | ||
3924 | __u32 j, pword; | ||
3925 | __u8 err = 0; | ||
3926 | |||
3927 | if(smctr_debug > 10) | ||
3928 | printk(KERN_DEBUG "%s: smctr_ram_memory_test\n", dev->name); | ||
3929 | |||
3930 | start_pattern = 0x0001; | ||
3931 | pages_of_ram = tp->ram_size / tp->ram_usable; | ||
3932 | pword = tp->ram_access; | ||
3933 | |||
3934 | /* Incremental word ODD boundary test. */ | ||
3935 | for(page = 0; (page < pages_of_ram) && (~err); | ||
3936 | page++, start_pattern += 0x8000) | ||
3937 | { | ||
3938 | smctr_set_page(dev, (__u8 *)(tp->ram_access | ||
3939 | + (page * tp->ram_usable * 1024) + 1)); | ||
3940 | word_pattern = start_pattern; | ||
3941 | |||
3942 | for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1; j += 2) | ||
3943 | *(__u16 *)(pword + j) = word_pattern++; | ||
3944 | |||
3945 | word_pattern = start_pattern; | ||
3946 | |||
3947 | for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1 | ||
3948 | && (~err); j += 2, word_pattern++) | ||
3949 | { | ||
3950 | word_read = *(__u16 *)(pword + j); | ||
3951 | if(word_read != word_pattern) | ||
3952 | { | ||
3953 | err = (__u8)1; | ||
3954 | err_offset = j; | ||
3955 | err_word = word_read; | ||
3956 | err_pattern = word_pattern; | ||
3957 | return (RAM_TEST_FAILED); | ||
3958 | } | ||
3959 | } | ||
3960 | } | ||
3961 | |||
3962 | /* Zero out memory. */ | ||
3963 | for(page = 0; page < pages_of_ram && (~err); page++) | ||
3964 | { | ||
3965 | smctr_set_page(dev, (__u8 *)(tp->ram_access | ||
3966 | + (page * tp->ram_usable * 1024))); | ||
3967 | word_pattern = 0; | ||
3968 | |||
3969 | for(j = 0; j < (__u32)tp->ram_usable * 1024; j +=2) | ||
3970 | *(__u16 *)(pword + j) = word_pattern; | ||
3971 | |||
3972 | for(j =0; j < (__u32)tp->ram_usable * 1024 | ||
3973 | && (~err); j += 2) | ||
3974 | { | ||
3975 | word_read = *(__u16 *)(pword + j); | ||
3976 | if(word_read != word_pattern) | ||
3977 | { | ||
3978 | err = (__u8)1; | ||
3979 | err_offset = j; | ||
3980 | err_word = word_read; | ||
3981 | err_pattern = word_pattern; | ||
3982 | return (RAM_TEST_FAILED); | ||
3983 | } | ||
3984 | } | ||
3985 | } | ||
3986 | |||
3987 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
3988 | |||
3989 | return (0); | ||
3990 | } | ||
3991 | |||
3992 | static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, | ||
3993 | __u16 *correlator) | ||
3994 | { | ||
3995 | MAC_SUB_VECTOR *rsv; | ||
3996 | signed short vlen; | ||
3997 | __u16 rcode = POSITIVE_ACK; | ||
3998 | unsigned int svectors = F_NO_SUB_VECTORS_FOUND; | ||
3999 | |||
4000 | /* This Frame can only come from a CRS */ | ||
4001 | if((rmf->dc_sc & SC_MASK) != SC_CRS) | ||
4002 | return(E_INAPPROPRIATE_SOURCE_CLASS); | ||
4003 | |||
4004 | /* Remove MVID Length from total length. */ | ||
4005 | vlen = (signed short)rmf->vl - 4; | ||
4006 | |||
4007 | /* Point to First SVID */ | ||
4008 | rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); | ||
4009 | |||
4010 | /* Search for Appropriate SVID's. */ | ||
4011 | while((vlen > 0) && (rcode == POSITIVE_ACK)) | ||
4012 | { | ||
4013 | switch(rsv->svi) | ||
4014 | { | ||
4015 | case CORRELATOR: | ||
4016 | svectors |= F_CORRELATOR; | ||
4017 | rcode = smctr_set_corr(dev, rsv, correlator); | ||
4018 | break; | ||
4019 | |||
4020 | case LOCAL_RING_NUMBER: | ||
4021 | svectors |= F_LOCAL_RING_NUMBER; | ||
4022 | rcode = smctr_set_local_ring_num(dev, rsv); | ||
4023 | break; | ||
4024 | |||
4025 | case ASSIGN_PHYSICAL_DROP: | ||
4026 | svectors |= F_ASSIGN_PHYSICAL_DROP; | ||
4027 | rcode = smctr_set_phy_drop(dev, rsv); | ||
4028 | break; | ||
4029 | |||
4030 | case ERROR_TIMER_VALUE: | ||
4031 | svectors |= F_ERROR_TIMER_VALUE; | ||
4032 | rcode = smctr_set_error_timer_value(dev, rsv); | ||
4033 | break; | ||
4034 | |||
4035 | case AUTHORIZED_FUNCTION_CLASS: | ||
4036 | svectors |= F_AUTHORIZED_FUNCTION_CLASS; | ||
4037 | rcode = smctr_set_auth_funct_class(dev, rsv); | ||
4038 | break; | ||
4039 | |||
4040 | case AUTHORIZED_ACCESS_PRIORITY: | ||
4041 | svectors |= F_AUTHORIZED_ACCESS_PRIORITY; | ||
4042 | rcode = smctr_set_auth_access_pri(dev, rsv); | ||
4043 | break; | ||
4044 | |||
4045 | default: | ||
4046 | rcode = E_SUB_VECTOR_UNKNOWN; | ||
4047 | break; | ||
4048 | } | ||
4049 | |||
4050 | /* Let Sender Know if SUM of SV length's is | ||
4051 | * larger then length in MVID length field | ||
4052 | */ | ||
4053 | if((vlen -= rsv->svl) < 0) | ||
4054 | rcode = E_VECTOR_LENGTH_ERROR; | ||
4055 | |||
4056 | rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); | ||
4057 | } | ||
4058 | |||
4059 | if(rcode == POSITIVE_ACK) | ||
4060 | { | ||
4061 | /* Let Sender Know if MVID length field | ||
4062 | * is larger then SUM of SV length's | ||
4063 | */ | ||
4064 | if(vlen != 0) | ||
4065 | rcode = E_VECTOR_LENGTH_ERROR; | ||
4066 | else | ||
4067 | { | ||
4068 | /* Let Sender Know if Expected SVID Missing */ | ||
4069 | if((svectors & R_CHG_PARM) ^ R_CHG_PARM) | ||
4070 | rcode = E_MISSING_SUB_VECTOR; | ||
4071 | } | ||
4072 | } | ||
4073 | |||
4074 | return (rcode); | ||
4075 | } | ||
4076 | |||
4077 | static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, | ||
4078 | __u16 *correlator) | ||
4079 | { | ||
4080 | MAC_SUB_VECTOR *rsv; | ||
4081 | signed short vlen; | ||
4082 | __u16 rcode = POSITIVE_ACK; | ||
4083 | unsigned int svectors = F_NO_SUB_VECTORS_FOUND; | ||
4084 | |||
4085 | /* This Frame can only come from a RPS */ | ||
4086 | if((rmf->dc_sc & SC_MASK) != SC_RPS) | ||
4087 | return (E_INAPPROPRIATE_SOURCE_CLASS); | ||
4088 | |||
4089 | /* Remove MVID Length from total length. */ | ||
4090 | vlen = (signed short)rmf->vl - 4; | ||
4091 | |||
4092 | /* Point to First SVID */ | ||
4093 | rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); | ||
4094 | |||
4095 | /* Search for Appropriate SVID's */ | ||
4096 | while((vlen > 0) && (rcode == POSITIVE_ACK)) | ||
4097 | { | ||
4098 | switch(rsv->svi) | ||
4099 | { | ||
4100 | case CORRELATOR: | ||
4101 | svectors |= F_CORRELATOR; | ||
4102 | rcode = smctr_set_corr(dev, rsv, correlator); | ||
4103 | break; | ||
4104 | |||
4105 | case LOCAL_RING_NUMBER: | ||
4106 | svectors |= F_LOCAL_RING_NUMBER; | ||
4107 | rcode = smctr_set_local_ring_num(dev, rsv); | ||
4108 | break; | ||
4109 | |||
4110 | case ASSIGN_PHYSICAL_DROP: | ||
4111 | svectors |= F_ASSIGN_PHYSICAL_DROP; | ||
4112 | rcode = smctr_set_phy_drop(dev, rsv); | ||
4113 | break; | ||
4114 | |||
4115 | case ERROR_TIMER_VALUE: | ||
4116 | svectors |= F_ERROR_TIMER_VALUE; | ||
4117 | rcode = smctr_set_error_timer_value(dev, rsv); | ||
4118 | break; | ||
4119 | |||
4120 | default: | ||
4121 | rcode = E_SUB_VECTOR_UNKNOWN; | ||
4122 | break; | ||
4123 | } | ||
4124 | |||
4125 | /* Let Sender Know if SUM of SV length's is | ||
4126 | * larger then length in MVID length field | ||
4127 | */ | ||
4128 | if((vlen -= rsv->svl) < 0) | ||
4129 | rcode = E_VECTOR_LENGTH_ERROR; | ||
4130 | |||
4131 | rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); | ||
4132 | } | ||
4133 | |||
4134 | if(rcode == POSITIVE_ACK) | ||
4135 | { | ||
4136 | /* Let Sender Know if MVID length field | ||
4137 | * is larger then SUM of SV length's | ||
4138 | */ | ||
4139 | if(vlen != 0) | ||
4140 | rcode = E_VECTOR_LENGTH_ERROR; | ||
4141 | else | ||
4142 | { | ||
4143 | /* Let Sender Know if Expected SV Missing */ | ||
4144 | if((svectors & R_INIT) ^ R_INIT) | ||
4145 | rcode = E_MISSING_SUB_VECTOR; | ||
4146 | } | ||
4147 | } | ||
4148 | |||
4149 | return (rcode); | ||
4150 | } | ||
4151 | |||
4152 | static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) | ||
4153 | { | ||
4154 | MAC_SUB_VECTOR *rsv; | ||
4155 | signed short vlen; | ||
4156 | __u16 rcode = POSITIVE_ACK; | ||
4157 | unsigned int svectors = F_NO_SUB_VECTORS_FOUND; | ||
4158 | |||
4159 | /* This Frame can only come from a CRS */ | ||
4160 | if((rmf->dc_sc & SC_MASK) != SC_CRS) | ||
4161 | return (E_INAPPROPRIATE_SOURCE_CLASS); | ||
4162 | |||
4163 | /* Remove MVID Length from total length */ | ||
4164 | vlen = (signed short)rmf->vl - 4; | ||
4165 | |||
4166 | /* Point to First SVID */ | ||
4167 | rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); | ||
4168 | |||
4169 | /* Search for Appropriate SVID's */ | ||
4170 | while((vlen > 0) && (rcode == POSITIVE_ACK)) | ||
4171 | { | ||
4172 | switch(rsv->svi) | ||
4173 | { | ||
4174 | case FRAME_FORWARD: | ||
4175 | svectors |= F_FRAME_FORWARD; | ||
4176 | rcode = smctr_set_frame_forward(dev, rsv, | ||
4177 | rmf->dc_sc); | ||
4178 | break; | ||
4179 | |||
4180 | default: | ||
4181 | rcode = E_SUB_VECTOR_UNKNOWN; | ||
4182 | break; | ||
4183 | } | ||
4184 | |||
4185 | /* Let Sender Know if SUM of SV length's is | ||
4186 | * larger then length in MVID length field | ||
4187 | */ | ||
4188 | if((vlen -= rsv->svl) < 0) | ||
4189 | rcode = E_VECTOR_LENGTH_ERROR; | ||
4190 | |||
4191 | rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); | ||
4192 | } | ||
4193 | |||
4194 | if(rcode == POSITIVE_ACK) | ||
4195 | { | ||
4196 | /* Let Sender Know if MVID length field | ||
4197 | * is larger then SUM of SV length's | ||
4198 | */ | ||
4199 | if(vlen != 0) | ||
4200 | rcode = E_VECTOR_LENGTH_ERROR; | ||
4201 | else | ||
4202 | { | ||
4203 | /* Let Sender Know if Expected SV Missing */ | ||
4204 | if((svectors & R_TX_FORWARD) ^ R_TX_FORWARD) | ||
4205 | rcode = E_MISSING_SUB_VECTOR; | ||
4206 | } | ||
4207 | } | ||
4208 | |||
4209 | return (rcode); | ||
4210 | } | ||
4211 | |||
4212 | static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, | ||
4213 | MAC_HEADER *rmf, __u16 *correlator) | ||
4214 | { | ||
4215 | MAC_SUB_VECTOR *rsv; | ||
4216 | signed short vlen; | ||
4217 | __u16 rcode = POSITIVE_ACK; | ||
4218 | unsigned int svectors = F_NO_SUB_VECTORS_FOUND; | ||
4219 | |||
4220 | /* Remove MVID Length from total length */ | ||
4221 | vlen = (signed short)rmf->vl - 4; | ||
4222 | |||
4223 | /* Point to First SVID */ | ||
4224 | rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); | ||
4225 | |||
4226 | /* Search for Appropriate SVID's */ | ||
4227 | while((vlen > 0) && (rcode == POSITIVE_ACK)) | ||
4228 | { | ||
4229 | switch(rsv->svi) | ||
4230 | { | ||
4231 | case CORRELATOR: | ||
4232 | svectors |= F_CORRELATOR; | ||
4233 | rcode = smctr_set_corr(dev, rsv, correlator); | ||
4234 | break; | ||
4235 | |||
4236 | default: | ||
4237 | rcode = E_SUB_VECTOR_UNKNOWN; | ||
4238 | break; | ||
4239 | } | ||
4240 | |||
4241 | /* Let Sender Know if SUM of SV length's is | ||
4242 | * larger then length in MVID length field | ||
4243 | */ | ||
4244 | if((vlen -= rsv->svl) < 0) | ||
4245 | rcode = E_VECTOR_LENGTH_ERROR; | ||
4246 | |||
4247 | rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); | ||
4248 | } | ||
4249 | |||
4250 | if(rcode == POSITIVE_ACK) | ||
4251 | { | ||
4252 | /* Let Sender Know if MVID length field | ||
4253 | * is larger then SUM of SV length's | ||
4254 | */ | ||
4255 | if(vlen != 0) | ||
4256 | rcode = E_VECTOR_LENGTH_ERROR; | ||
4257 | else | ||
4258 | { | ||
4259 | /* Let Sender Know if Expected SVID Missing */ | ||
4260 | if((svectors & R_RQ_ATTCH_STATE_ADDR) | ||
4261 | ^ R_RQ_ATTCH_STATE_ADDR) | ||
4262 | rcode = E_MISSING_SUB_VECTOR; | ||
4263 | } | ||
4264 | } | ||
4265 | |||
4266 | return (rcode); | ||
4267 | } | ||
4268 | |||
4269 | static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, | ||
4270 | __u16 *correlator) | ||
4271 | { | ||
4272 | MAC_SUB_VECTOR *rsv; | ||
4273 | signed short vlen; | ||
4274 | |||
4275 | *correlator = 0; | ||
4276 | |||
4277 | /* Remove MVID Length from total length */ | ||
4278 | vlen = (signed short)rmf->vl - 4; | ||
4279 | |||
4280 | /* Point to First SVID */ | ||
4281 | rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); | ||
4282 | |||
4283 | /* Search for CORRELATOR for RSP to UNKNOWN */ | ||
4284 | while((vlen > 0) && (*correlator == 0)) | ||
4285 | { | ||
4286 | switch(rsv->svi) | ||
4287 | { | ||
4288 | case CORRELATOR: | ||
4289 | smctr_set_corr(dev, rsv, correlator); | ||
4290 | break; | ||
4291 | |||
4292 | default: | ||
4293 | break; | ||
4294 | } | ||
4295 | |||
4296 | vlen -= rsv->svl; | ||
4297 | rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); | ||
4298 | } | ||
4299 | |||
4300 | return (E_UNRECOGNIZED_VECTOR_ID); | ||
4301 | } | ||
4302 | |||
4303 | /* | ||
4304 | * Reset the 825 NIC and exit w: | ||
4305 | * 1. The NIC reset cleared (non-reset state), halted and un-initialized. | ||
4306 | * 2. TINT masked. | ||
4307 | * 3. CBUSY masked. | ||
4308 | * 4. TINT clear. | ||
4309 | * 5. CBUSY clear. | ||
4310 | */ | ||
4311 | static int smctr_reset_adapter(struct net_device *dev) | ||
4312 | { | ||
4313 | struct net_local *tp = netdev_priv(dev); | ||
4314 | int ioaddr = dev->base_addr; | ||
4315 | |||
4316 | /* Reseting the NIC will put it in a halted and un-initialized state. */ smctr_set_trc_reset(ioaddr); | ||
4317 | mdelay(200); /* ~2 ms */ | ||
4318 | |||
4319 | smctr_clear_trc_reset(ioaddr); | ||
4320 | mdelay(200); /* ~2 ms */ | ||
4321 | |||
4322 | /* Remove any latched interrupts that occurred prior to reseting the | ||
4323 | * adapter or possibily caused by line glitches due to the reset. | ||
4324 | */ | ||
4325 | outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR); | ||
4326 | |||
4327 | return (0); | ||
4328 | } | ||
4329 | |||
4330 | static int smctr_restart_tx_chain(struct net_device *dev, short queue) | ||
4331 | { | ||
4332 | struct net_local *tp = netdev_priv(dev); | ||
4333 | int err = 0; | ||
4334 | |||
4335 | if(smctr_debug > 10) | ||
4336 | printk(KERN_DEBUG "%s: smctr_restart_tx_chain\n", dev->name); | ||
4337 | |||
4338 | if(tp->num_tx_fcbs_used[queue] != 0 | ||
4339 | && tp->tx_queue_status[queue] == NOT_TRANSMITING) | ||
4340 | { | ||
4341 | tp->tx_queue_status[queue] = TRANSMITING; | ||
4342 | err = smctr_issue_resume_tx_fcb_cmd(dev, queue); | ||
4343 | } | ||
4344 | |||
4345 | return (err); | ||
4346 | } | ||
4347 | |||
4348 | static int smctr_ring_status_chg(struct net_device *dev) | ||
4349 | { | ||
4350 | struct net_local *tp = netdev_priv(dev); | ||
4351 | |||
4352 | if(smctr_debug > 10) | ||
4353 | printk(KERN_DEBUG "%s: smctr_ring_status_chg\n", dev->name); | ||
4354 | |||
4355 | /* Check for ring_status_flag: whenever MONITOR_STATE_BIT | ||
4356 | * Bit is set, check value of monitor_state, only then we | ||
4357 | * enable and start transmit/receive timeout (if and only | ||
4358 | * if it is MS_ACTIVE_MONITOR_STATE or MS_STANDBY_MONITOR_STATE) | ||
4359 | */ | ||
4360 | if(tp->ring_status_flags == MONITOR_STATE_CHANGED) | ||
4361 | { | ||
4362 | if((tp->monitor_state == MS_ACTIVE_MONITOR_STATE) | ||
4363 | || (tp->monitor_state == MS_STANDBY_MONITOR_STATE)) | ||
4364 | { | ||
4365 | tp->monitor_state_ready = 1; | ||
4366 | } | ||
4367 | else | ||
4368 | { | ||
4369 | /* if adapter is NOT in either active monitor | ||
4370 | * or standby monitor state => Disable | ||
4371 | * transmit/receive timeout. | ||
4372 | */ | ||
4373 | tp->monitor_state_ready = 0; | ||
4374 | |||
4375 | /* Ring speed problem, switching to auto mode. */ | ||
4376 | if(tp->monitor_state == MS_MONITOR_FSM_INACTIVE | ||
4377 | && !tp->cleanup) | ||
4378 | { | ||
4379 | printk(KERN_INFO "%s: Incorrect ring speed switching.\n", | ||
4380 | dev->name); | ||
4381 | smctr_set_ring_speed(dev); | ||
4382 | } | ||
4383 | } | ||
4384 | } | ||
4385 | |||
4386 | if(!(tp->ring_status_flags & RING_STATUS_CHANGED)) | ||
4387 | return (0); | ||
4388 | |||
4389 | switch(tp->ring_status) | ||
4390 | { | ||
4391 | case RING_RECOVERY: | ||
4392 | printk(KERN_INFO "%s: Ring Recovery\n", dev->name); | ||
4393 | tp->current_ring_status |= RING_RECOVERY; | ||
4394 | break; | ||
4395 | |||
4396 | case SINGLE_STATION: | ||
4397 | printk(KERN_INFO "%s: Single Statinon\n", dev->name); | ||
4398 | tp->current_ring_status |= SINGLE_STATION; | ||
4399 | break; | ||
4400 | |||
4401 | case COUNTER_OVERFLOW: | ||
4402 | printk(KERN_INFO "%s: Counter Overflow\n", dev->name); | ||
4403 | tp->current_ring_status |= COUNTER_OVERFLOW; | ||
4404 | break; | ||
4405 | |||
4406 | case REMOVE_RECEIVED: | ||
4407 | printk(KERN_INFO "%s: Remove Received\n", dev->name); | ||
4408 | tp->current_ring_status |= REMOVE_RECEIVED; | ||
4409 | break; | ||
4410 | |||
4411 | case AUTO_REMOVAL_ERROR: | ||
4412 | printk(KERN_INFO "%s: Auto Remove Error\n", dev->name); | ||
4413 | tp->current_ring_status |= AUTO_REMOVAL_ERROR; | ||
4414 | break; | ||
4415 | |||
4416 | case LOBE_WIRE_FAULT: | ||
4417 | printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name); | ||
4418 | tp->current_ring_status |= LOBE_WIRE_FAULT; | ||
4419 | break; | ||
4420 | |||
4421 | case TRANSMIT_BEACON: | ||
4422 | printk(KERN_INFO "%s: Transmit Beacon\n", dev->name); | ||
4423 | tp->current_ring_status |= TRANSMIT_BEACON; | ||
4424 | break; | ||
4425 | |||
4426 | case SOFT_ERROR: | ||
4427 | printk(KERN_INFO "%s: Soft Error\n", dev->name); | ||
4428 | tp->current_ring_status |= SOFT_ERROR; | ||
4429 | break; | ||
4430 | |||
4431 | case HARD_ERROR: | ||
4432 | printk(KERN_INFO "%s: Hard Error\n", dev->name); | ||
4433 | tp->current_ring_status |= HARD_ERROR; | ||
4434 | break; | ||
4435 | |||
4436 | case SIGNAL_LOSS: | ||
4437 | printk(KERN_INFO "%s: Signal Loss\n", dev->name); | ||
4438 | tp->current_ring_status |= SIGNAL_LOSS; | ||
4439 | break; | ||
4440 | |||
4441 | default: | ||
4442 | printk(KERN_INFO "%s: Unknown ring status change\n", | ||
4443 | dev->name); | ||
4444 | break; | ||
4445 | } | ||
4446 | |||
4447 | return (0); | ||
4448 | } | ||
4449 | |||
4450 | static int smctr_rx_frame(struct net_device *dev) | ||
4451 | { | ||
4452 | struct net_local *tp = netdev_priv(dev); | ||
4453 | __u16 queue, status, rx_size, err = 0; | ||
4454 | __u8 *pbuff; | ||
4455 | |||
4456 | if(smctr_debug > 10) | ||
4457 | printk(KERN_DEBUG "%s: smctr_rx_frame\n", dev->name); | ||
4458 | |||
4459 | queue = tp->receive_queue_number; | ||
4460 | |||
4461 | while((status = tp->rx_fcb_curr[queue]->frame_status) != SUCCESS) | ||
4462 | { | ||
4463 | err = HARDWARE_FAILED; | ||
4464 | |||
4465 | if(((status & 0x007f) == 0) | ||
4466 | || ((tp->receive_mask & ACCEPT_ERR_PACKETS) != 0)) | ||
4467 | { | ||
4468 | /* frame length less the CRC (4 bytes) + FS (1 byte) */ | ||
4469 | rx_size = tp->rx_fcb_curr[queue]->frame_length - 5; | ||
4470 | |||
4471 | pbuff = smctr_get_rx_pointer(dev, queue); | ||
4472 | |||
4473 | smctr_set_page(dev, pbuff); | ||
4474 | smctr_disable_16bit(dev); | ||
4475 | |||
4476 | /* pbuff points to addr within one page */ | ||
4477 | pbuff = (__u8 *)PAGE_POINTER(pbuff); | ||
4478 | |||
4479 | if(queue == NON_MAC_QUEUE) | ||
4480 | { | ||
4481 | struct sk_buff *skb; | ||
4482 | |||
4483 | skb = dev_alloc_skb(rx_size); | ||
4484 | if (skb) { | ||
4485 | skb_put(skb, rx_size); | ||
4486 | |||
4487 | memcpy(skb->data, pbuff, rx_size); | ||
4488 | |||
4489 | /* Update Counters */ | ||
4490 | tp->MacStat.rx_packets++; | ||
4491 | tp->MacStat.rx_bytes += skb->len; | ||
4492 | |||
4493 | /* Kick the packet on up. */ | ||
4494 | skb->dev = dev; | ||
4495 | skb->protocol = tr_type_trans(skb, dev); | ||
4496 | netif_rx(skb); | ||
4497 | dev->last_rx = jiffies; | ||
4498 | } else { | ||
4499 | } | ||
4500 | } | ||
4501 | else | ||
4502 | smctr_process_rx_packet((MAC_HEADER *)pbuff, | ||
4503 | rx_size, dev, status); | ||
4504 | } | ||
4505 | |||
4506 | smctr_enable_16bit(dev); | ||
4507 | smctr_set_page(dev, (__u8 *)tp->ram_access); | ||
4508 | smctr_update_rx_chain(dev, queue); | ||
4509 | |||
4510 | if(err != SUCCESS) | ||
4511 | break; | ||
4512 | } | ||
4513 | |||
4514 | return (err); | ||
4515 | } | ||
4516 | |||
4517 | static int smctr_send_dat(struct net_device *dev) | ||
4518 | { | ||
4519 | struct net_local *tp = netdev_priv(dev); | ||
4520 | unsigned int i, err; | ||
4521 | MAC_HEADER *tmf; | ||
4522 | FCBlock *fcb; | ||
4523 | |||
4524 | if(smctr_debug > 10) | ||
4525 | printk(KERN_DEBUG "%s: smctr_send_dat\n", dev->name); | ||
4526 | |||
4527 | if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, | ||
4528 | sizeof(MAC_HEADER))) == (FCBlock *)(-1L)) | ||
4529 | { | ||
4530 | return (OUT_OF_RESOURCES); | ||
4531 | } | ||
4532 | |||
4533 | /* Initialize DAT Data Fields. */ | ||
4534 | tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; | ||
4535 | tmf->ac = MSB(AC_FC_DAT); | ||
4536 | tmf->fc = LSB(AC_FC_DAT); | ||
4537 | |||
4538 | for(i = 0; i < 6; i++) | ||
4539 | { | ||
4540 | tmf->sa[i] = dev->dev_addr[i]; | ||
4541 | tmf->da[i] = dev->dev_addr[i]; | ||
4542 | |||
4543 | } | ||
4544 | |||
4545 | tmf->vc = DAT; | ||
4546 | tmf->dc_sc = DC_RS | SC_RS; | ||
4547 | tmf->vl = 4; | ||
4548 | tmf->vl = SWAP_BYTES(tmf->vl); | ||
4549 | |||
4550 | /* Start Transmit. */ | ||
4551 | if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) | ||
4552 | return (err); | ||
4553 | |||
4554 | /* Wait for Transmit to Complete */ | ||
4555 | for(i = 0; i < 10000; i++) | ||
4556 | { | ||
4557 | if(fcb->frame_status & FCB_COMMAND_DONE) | ||
4558 | break; | ||
4559 | mdelay(1); | ||
4560 | } | ||
4561 | |||
4562 | /* Check if GOOD frame Tx'ed. */ | ||
4563 | if(!(fcb->frame_status & FCB_COMMAND_DONE) | ||
4564 | || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) | ||
4565 | { | ||
4566 | return (INITIALIZE_FAILED); | ||
4567 | } | ||
4568 | |||
4569 | /* De-allocated Tx FCB and Frame Buffer | ||
4570 | * The FCB must be de-allocated manually if executing with | ||
4571 | * interrupts disabled, other wise the ISR (LM_Service_Events) | ||
4572 | * will de-allocate it when the interrupt occurs. | ||
4573 | */ | ||
4574 | tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; | ||
4575 | smctr_update_tx_chain(dev, fcb, MAC_QUEUE); | ||
4576 | |||
4577 | return (0); | ||
4578 | } | ||
4579 | |||
4580 | static void smctr_timeout(struct net_device *dev) | ||
4581 | { | ||
4582 | /* | ||
4583 | * If we get here, some higher level has decided we are broken. | ||
4584 | * There should really be a "kick me" function call instead. | ||
4585 | * | ||
4586 | * Resetting the token ring adapter takes a long time so just | ||
4587 | * fake transmission time and go on trying. Our own timeout | ||
4588 | * routine is in sktr_timer_chk() | ||
4589 | */ | ||
4590 | dev->trans_start = jiffies; | ||
4591 | netif_wake_queue(dev); | ||
4592 | } | ||
4593 | |||
4594 | /* | ||
4595 | * Gets skb from system, queues it and checks if it can be sent | ||
4596 | */ | ||
4597 | static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev) | ||
4598 | { | ||
4599 | struct net_local *tp = netdev_priv(dev); | ||
4600 | |||
4601 | if(smctr_debug > 10) | ||
4602 | printk(KERN_DEBUG "%s: smctr_send_packet\n", dev->name); | ||
4603 | |||
4604 | /* | ||
4605 | * Block a transmit overlap | ||
4606 | */ | ||
4607 | |||
4608 | netif_stop_queue(dev); | ||
4609 | |||
4610 | if(tp->QueueSkb == 0) | ||
4611 | return (1); /* Return with tbusy set: queue full */ | ||
4612 | |||
4613 | tp->QueueSkb--; | ||
4614 | skb_queue_tail(&tp->SendSkbQueue, skb); | ||
4615 | smctr_hardware_send_packet(dev, tp); | ||
4616 | if(tp->QueueSkb > 0) | ||
4617 | netif_wake_queue(dev); | ||
4618 | |||
4619 | return (0); | ||
4620 | } | ||
4621 | |||
4622 | static int smctr_send_lobe_media_test(struct net_device *dev) | ||
4623 | { | ||
4624 | struct net_local *tp = netdev_priv(dev); | ||
4625 | MAC_SUB_VECTOR *tsv; | ||
4626 | MAC_HEADER *tmf; | ||
4627 | FCBlock *fcb; | ||
4628 | __u32 i; | ||
4629 | int err; | ||
4630 | |||
4631 | if(smctr_debug > 15) | ||
4632 | printk(KERN_DEBUG "%s: smctr_send_lobe_media_test\n", dev->name); | ||
4633 | |||
4634 | if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr) | ||
4635 | + S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L)) | ||
4636 | { | ||
4637 | return (OUT_OF_RESOURCES); | ||
4638 | } | ||
4639 | |||
4640 | /* Initialize DAT Data Fields. */ | ||
4641 | tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; | ||
4642 | tmf->ac = MSB(AC_FC_LOBE_MEDIA_TEST); | ||
4643 | tmf->fc = LSB(AC_FC_LOBE_MEDIA_TEST); | ||
4644 | |||
4645 | for(i = 0; i < 6; i++) | ||
4646 | { | ||
4647 | tmf->da[i] = 0; | ||
4648 | tmf->sa[i] = dev->dev_addr[i]; | ||
4649 | } | ||
4650 | |||
4651 | tmf->vc = LOBE_MEDIA_TEST; | ||
4652 | tmf->dc_sc = DC_RS | SC_RS; | ||
4653 | tmf->vl = 4; | ||
4654 | |||
4655 | tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); | ||
4656 | smctr_make_wrap_data(dev, tsv); | ||
4657 | tmf->vl += tsv->svl; | ||
4658 | |||
4659 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4660 | smctr_make_wrap_data(dev, tsv); | ||
4661 | tmf->vl += tsv->svl; | ||
4662 | |||
4663 | /* Start Transmit. */ | ||
4664 | tmf->vl = SWAP_BYTES(tmf->vl); | ||
4665 | if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) | ||
4666 | return (err); | ||
4667 | |||
4668 | /* Wait for Transmit to Complete. (10 ms). */ | ||
4669 | for(i=0; i < 10000; i++) | ||
4670 | { | ||
4671 | if(fcb->frame_status & FCB_COMMAND_DONE) | ||
4672 | break; | ||
4673 | mdelay(1); | ||
4674 | } | ||
4675 | |||
4676 | /* Check if GOOD frame Tx'ed */ | ||
4677 | if(!(fcb->frame_status & FCB_COMMAND_DONE) | ||
4678 | || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) | ||
4679 | { | ||
4680 | return (LOBE_MEDIA_TEST_FAILED); | ||
4681 | } | ||
4682 | |||
4683 | /* De-allocated Tx FCB and Frame Buffer | ||
4684 | * The FCB must be de-allocated manually if executing with | ||
4685 | * interrupts disabled, other wise the ISR (LM_Service_Events) | ||
4686 | * will de-allocate it when the interrupt occurs. | ||
4687 | */ | ||
4688 | tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; | ||
4689 | smctr_update_tx_chain(dev, fcb, MAC_QUEUE); | ||
4690 | |||
4691 | return (0); | ||
4692 | } | ||
4693 | |||
4694 | static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, | ||
4695 | __u16 correlator) | ||
4696 | { | ||
4697 | MAC_HEADER *tmf; | ||
4698 | MAC_SUB_VECTOR *tsv; | ||
4699 | FCBlock *fcb; | ||
4700 | |||
4701 | if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) | ||
4702 | + S_CORRELATOR + S_PHYSICAL_DROP + S_UPSTREAM_NEIGHBOR_ADDRESS | ||
4703 | + S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS)) | ||
4704 | == (FCBlock *)(-1L)) | ||
4705 | { | ||
4706 | return (0); | ||
4707 | } | ||
4708 | |||
4709 | tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; | ||
4710 | tmf->vc = RPT_ADDR; | ||
4711 | tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; | ||
4712 | tmf->vl = 4; | ||
4713 | |||
4714 | smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ADDR); | ||
4715 | |||
4716 | tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); | ||
4717 | smctr_make_corr(dev, tsv, correlator); | ||
4718 | |||
4719 | tmf->vl += tsv->svl; | ||
4720 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4721 | smctr_make_phy_drop_num(dev, tsv); | ||
4722 | |||
4723 | tmf->vl += tsv->svl; | ||
4724 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4725 | smctr_make_upstream_neighbor_addr(dev, tsv); | ||
4726 | |||
4727 | tmf->vl += tsv->svl; | ||
4728 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4729 | smctr_make_addr_mod(dev, tsv); | ||
4730 | |||
4731 | tmf->vl += tsv->svl; | ||
4732 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4733 | smctr_make_group_addr(dev, tsv); | ||
4734 | |||
4735 | tmf->vl += tsv->svl; | ||
4736 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4737 | smctr_make_funct_addr(dev, tsv); | ||
4738 | |||
4739 | tmf->vl += tsv->svl; | ||
4740 | |||
4741 | /* Subtract out MVID and MVL which is | ||
4742 | * include in both vl and MAC_HEADER | ||
4743 | */ | ||
4744 | /* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4745 | fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4746 | */ | ||
4747 | tmf->vl = SWAP_BYTES(tmf->vl); | ||
4748 | |||
4749 | return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); | ||
4750 | } | ||
4751 | |||
4752 | static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, | ||
4753 | __u16 correlator) | ||
4754 | { | ||
4755 | MAC_HEADER *tmf; | ||
4756 | MAC_SUB_VECTOR *tsv; | ||
4757 | FCBlock *fcb; | ||
4758 | |||
4759 | if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) | ||
4760 | + S_CORRELATOR + S_PRODUCT_INSTANCE_ID + S_FUNCTIONAL_ADDRESS | ||
4761 | + S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY)) | ||
4762 | == (FCBlock *)(-1L)) | ||
4763 | { | ||
4764 | return (0); | ||
4765 | } | ||
4766 | |||
4767 | tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; | ||
4768 | tmf->vc = RPT_ATTCH; | ||
4769 | tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; | ||
4770 | tmf->vl = 4; | ||
4771 | |||
4772 | smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ATTCH); | ||
4773 | |||
4774 | tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); | ||
4775 | smctr_make_corr(dev, tsv, correlator); | ||
4776 | |||
4777 | tmf->vl += tsv->svl; | ||
4778 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4779 | smctr_make_product_id(dev, tsv); | ||
4780 | |||
4781 | tmf->vl += tsv->svl; | ||
4782 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4783 | smctr_make_funct_addr(dev, tsv); | ||
4784 | |||
4785 | tmf->vl += tsv->svl; | ||
4786 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4787 | smctr_make_auth_funct_class(dev, tsv); | ||
4788 | |||
4789 | tmf->vl += tsv->svl; | ||
4790 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4791 | smctr_make_access_pri(dev, tsv); | ||
4792 | |||
4793 | tmf->vl += tsv->svl; | ||
4794 | |||
4795 | /* Subtract out MVID and MVL which is | ||
4796 | * include in both vl and MAC_HEADER | ||
4797 | */ | ||
4798 | /* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4799 | fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4800 | */ | ||
4801 | tmf->vl = SWAP_BYTES(tmf->vl); | ||
4802 | |||
4803 | return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); | ||
4804 | } | ||
4805 | |||
4806 | static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, | ||
4807 | __u16 correlator) | ||
4808 | { | ||
4809 | MAC_HEADER *tmf; | ||
4810 | MAC_SUB_VECTOR *tsv; | ||
4811 | FCBlock *fcb; | ||
4812 | |||
4813 | if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) | ||
4814 | + S_CORRELATOR + S_RING_STATION_VERSION_NUMBER | ||
4815 | + S_RING_STATION_STATUS + S_STATION_IDENTIFER)) | ||
4816 | == (FCBlock *)(-1L)) | ||
4817 | { | ||
4818 | return (0); | ||
4819 | } | ||
4820 | |||
4821 | tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; | ||
4822 | tmf->vc = RPT_STATE; | ||
4823 | tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; | ||
4824 | tmf->vl = 4; | ||
4825 | |||
4826 | smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_STATE); | ||
4827 | |||
4828 | tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); | ||
4829 | smctr_make_corr(dev, tsv, correlator); | ||
4830 | |||
4831 | tmf->vl += tsv->svl; | ||
4832 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4833 | smctr_make_ring_station_version(dev, tsv); | ||
4834 | |||
4835 | tmf->vl += tsv->svl; | ||
4836 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4837 | smctr_make_ring_station_status(dev, tsv); | ||
4838 | |||
4839 | tmf->vl += tsv->svl; | ||
4840 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4841 | smctr_make_station_id(dev, tsv); | ||
4842 | |||
4843 | tmf->vl += tsv->svl; | ||
4844 | |||
4845 | /* Subtract out MVID and MVL which is | ||
4846 | * include in both vl and MAC_HEADER | ||
4847 | */ | ||
4848 | /* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4849 | fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4850 | */ | ||
4851 | tmf->vl = SWAP_BYTES(tmf->vl); | ||
4852 | |||
4853 | return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); | ||
4854 | } | ||
4855 | |||
4856 | static int smctr_send_rpt_tx_forward(struct net_device *dev, | ||
4857 | MAC_HEADER *rmf, __u16 tx_fstatus) | ||
4858 | { | ||
4859 | MAC_HEADER *tmf; | ||
4860 | MAC_SUB_VECTOR *tsv; | ||
4861 | FCBlock *fcb; | ||
4862 | |||
4863 | if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) | ||
4864 | + S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L)) | ||
4865 | { | ||
4866 | return (0); | ||
4867 | } | ||
4868 | |||
4869 | tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; | ||
4870 | tmf->vc = RPT_TX_FORWARD; | ||
4871 | tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; | ||
4872 | tmf->vl = 4; | ||
4873 | |||
4874 | smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_TX_FORWARD); | ||
4875 | |||
4876 | tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); | ||
4877 | smctr_make_tx_status_code(dev, tsv, tx_fstatus); | ||
4878 | |||
4879 | tmf->vl += tsv->svl; | ||
4880 | |||
4881 | /* Subtract out MVID and MVL which is | ||
4882 | * include in both vl and MAC_HEADER | ||
4883 | */ | ||
4884 | /* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4885 | fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4886 | */ | ||
4887 | tmf->vl = SWAP_BYTES(tmf->vl); | ||
4888 | |||
4889 | return(smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); | ||
4890 | } | ||
4891 | |||
4892 | static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, | ||
4893 | __u16 rcode, __u16 correlator) | ||
4894 | { | ||
4895 | MAC_HEADER *tmf; | ||
4896 | MAC_SUB_VECTOR *tsv; | ||
4897 | FCBlock *fcb; | ||
4898 | |||
4899 | if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) | ||
4900 | + S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L)) | ||
4901 | { | ||
4902 | return (0); | ||
4903 | } | ||
4904 | |||
4905 | tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; | ||
4906 | tmf->vc = RSP; | ||
4907 | tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; | ||
4908 | tmf->vl = 4; | ||
4909 | |||
4910 | smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RSP); | ||
4911 | |||
4912 | tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); | ||
4913 | smctr_make_corr(dev, tsv, correlator); | ||
4914 | |||
4915 | return (0); | ||
4916 | } | ||
4917 | |||
4918 | static int smctr_send_rq_init(struct net_device *dev) | ||
4919 | { | ||
4920 | struct net_local *tp = netdev_priv(dev); | ||
4921 | MAC_HEADER *tmf; | ||
4922 | MAC_SUB_VECTOR *tsv; | ||
4923 | FCBlock *fcb; | ||
4924 | unsigned int i, count = 0; | ||
4925 | __u16 fstatus; | ||
4926 | int err; | ||
4927 | |||
4928 | do { | ||
4929 | if(((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) | ||
4930 | + S_PRODUCT_INSTANCE_ID + S_UPSTREAM_NEIGHBOR_ADDRESS | ||
4931 | + S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER)) | ||
4932 | == (FCBlock *)(-1L))) | ||
4933 | { | ||
4934 | return (0); | ||
4935 | } | ||
4936 | |||
4937 | tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; | ||
4938 | tmf->vc = RQ_INIT; | ||
4939 | tmf->dc_sc = DC_RPS | SC_RS; | ||
4940 | tmf->vl = 4; | ||
4941 | |||
4942 | smctr_make_8025_hdr(dev, NULL, tmf, AC_FC_RQ_INIT); | ||
4943 | |||
4944 | tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); | ||
4945 | smctr_make_product_id(dev, tsv); | ||
4946 | |||
4947 | tmf->vl += tsv->svl; | ||
4948 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4949 | smctr_make_upstream_neighbor_addr(dev, tsv); | ||
4950 | |||
4951 | tmf->vl += tsv->svl; | ||
4952 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4953 | smctr_make_ring_station_version(dev, tsv); | ||
4954 | |||
4955 | tmf->vl += tsv->svl; | ||
4956 | tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); | ||
4957 | smctr_make_addr_mod(dev, tsv); | ||
4958 | |||
4959 | tmf->vl += tsv->svl; | ||
4960 | |||
4961 | /* Subtract out MVID and MVL which is | ||
4962 | * include in both vl and MAC_HEADER | ||
4963 | */ | ||
4964 | /* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4965 | fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; | ||
4966 | */ | ||
4967 | tmf->vl = SWAP_BYTES(tmf->vl); | ||
4968 | |||
4969 | if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) | ||
4970 | return (err); | ||
4971 | |||
4972 | /* Wait for Transmit to Complete */ | ||
4973 | for(i = 0; i < 10000; i++) | ||
4974 | { | ||
4975 | if(fcb->frame_status & FCB_COMMAND_DONE) | ||
4976 | break; | ||
4977 | mdelay(1); | ||
4978 | } | ||
4979 | |||
4980 | /* Check if GOOD frame Tx'ed */ | ||
4981 | fstatus = fcb->frame_status; | ||
4982 | |||
4983 | if(!(fstatus & FCB_COMMAND_DONE)) | ||
4984 | return (HARDWARE_FAILED); | ||
4985 | |||
4986 | if(!(fstatus & FCB_TX_STATUS_E)) | ||
4987 | count++; | ||
4988 | |||
4989 | /* De-allocated Tx FCB and Frame Buffer | ||
4990 | * The FCB must be de-allocated manually if executing with | ||
4991 | * interrupts disabled, other wise the ISR (LM_Service_Events) | ||
4992 | * will de-allocate it when the interrupt occurs. | ||
4993 | */ | ||
4994 | tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; | ||
4995 | smctr_update_tx_chain(dev, fcb, MAC_QUEUE); | ||
4996 | } while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS)); | ||
4997 | |||
4998 | return (smctr_join_complete_state(dev)); | ||
4999 | } | ||
5000 | |||
5001 | static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, | ||
5002 | __u16 *tx_fstatus) | ||
5003 | { | ||
5004 | struct net_local *tp = netdev_priv(dev); | ||
5005 | FCBlock *fcb; | ||
5006 | unsigned int i; | ||
5007 | int err; | ||
5008 | |||
5009 | /* Check if this is the END POINT of the Transmit Forward Chain. */ | ||
5010 | if(rmf->vl <= 18) | ||
5011 | return (0); | ||
5012 | |||
5013 | /* Allocate Transmit FCB only by requesting 0 bytes | ||
5014 | * of data buffer. | ||
5015 | */ | ||
5016 | if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L)) | ||
5017 | return (0); | ||
5018 | |||
5019 | /* Set pointer to Transmit Frame Buffer to the data | ||
5020 | * portion of the received TX Forward frame, making | ||
5021 | * sure to skip over the Vector Code (vc) and Vector | ||
5022 | * length (vl). | ||
5023 | */ | ||
5024 | fcb->bdb_ptr->trc_data_block_ptr = TRC_POINTER((__u32)rmf | ||
5025 | + sizeof(MAC_HEADER) + 2); | ||
5026 | fcb->bdb_ptr->data_block_ptr = (__u16 *)((__u32)rmf | ||
5027 | + sizeof(MAC_HEADER) + 2); | ||
5028 | |||
5029 | fcb->frame_length = rmf->vl - 4 - 2; | ||
5030 | fcb->bdb_ptr->buffer_length = rmf->vl - 4 - 2; | ||
5031 | |||
5032 | if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) | ||
5033 | return (err); | ||
5034 | |||
5035 | /* Wait for Transmit to Complete */ | ||
5036 | for(i = 0; i < 10000; i++) | ||
5037 | { | ||
5038 | if(fcb->frame_status & FCB_COMMAND_DONE) | ||
5039 | break; | ||
5040 | mdelay(1); | ||
5041 | } | ||
5042 | |||
5043 | /* Check if GOOD frame Tx'ed */ | ||
5044 | if(!(fcb->frame_status & FCB_COMMAND_DONE)) | ||
5045 | { | ||
5046 | if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE))) | ||
5047 | return (err); | ||
5048 | |||
5049 | for(i = 0; i < 10000; i++) | ||
5050 | { | ||
5051 | if(fcb->frame_status & FCB_COMMAND_DONE) | ||
5052 | break; | ||
5053 | mdelay(1); | ||
5054 | } | ||
5055 | |||
5056 | if(!(fcb->frame_status & FCB_COMMAND_DONE)) | ||
5057 | return (HARDWARE_FAILED); | ||
5058 | } | ||
5059 | |||
5060 | *tx_fstatus = fcb->frame_status; | ||
5061 | |||
5062 | return (A_FRAME_WAS_FORWARDED); | ||
5063 | } | ||
5064 | |||
5065 | static int smctr_set_auth_access_pri(struct net_device *dev, | ||
5066 | MAC_SUB_VECTOR *rsv) | ||
5067 | { | ||
5068 | struct net_local *tp = netdev_priv(dev); | ||
5069 | |||
5070 | if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY) | ||
5071 | return (E_SUB_VECTOR_LENGTH_ERROR); | ||
5072 | |||
5073 | tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]); | ||
5074 | |||
5075 | return (POSITIVE_ACK); | ||
5076 | } | ||
5077 | |||
5078 | static int smctr_set_auth_funct_class(struct net_device *dev, | ||
5079 | MAC_SUB_VECTOR *rsv) | ||
5080 | { | ||
5081 | struct net_local *tp = netdev_priv(dev); | ||
5082 | |||
5083 | if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS) | ||
5084 | return (E_SUB_VECTOR_LENGTH_ERROR); | ||
5085 | |||
5086 | tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]); | ||
5087 | |||
5088 | return (POSITIVE_ACK); | ||
5089 | } | ||
5090 | |||
5091 | static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, | ||
5092 | __u16 *correlator) | ||
5093 | { | ||
5094 | if(rsv->svl != S_CORRELATOR) | ||
5095 | return (E_SUB_VECTOR_LENGTH_ERROR); | ||
5096 | |||
5097 | *correlator = (rsv->svv[0] << 8 | rsv->svv[1]); | ||
5098 | |||
5099 | return (POSITIVE_ACK); | ||
5100 | } | ||
5101 | |||
5102 | static int smctr_set_error_timer_value(struct net_device *dev, | ||
5103 | MAC_SUB_VECTOR *rsv) | ||
5104 | { | ||
5105 | __u16 err_tval; | ||
5106 | int err; | ||
5107 | |||
5108 | if(rsv->svl != S_ERROR_TIMER_VALUE) | ||
5109 | return (E_SUB_VECTOR_LENGTH_ERROR); | ||
5110 | |||
5111 | err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10; | ||
5112 | |||
5113 | smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval); | ||
5114 | |||
5115 | if((err = smctr_wait_cmd(dev))) | ||
5116 | return (err); | ||
5117 | |||
5118 | return (POSITIVE_ACK); | ||
5119 | } | ||
5120 | |||
5121 | static int smctr_set_frame_forward(struct net_device *dev, | ||
5122 | MAC_SUB_VECTOR *rsv, __u8 dc_sc) | ||
5123 | { | ||
5124 | if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD)) | ||
5125 | return (E_SUB_VECTOR_LENGTH_ERROR); | ||
5126 | |||
5127 | if((dc_sc & DC_MASK) != DC_CRS) | ||
5128 | { | ||
5129 | if(rsv->svl >= 2 && rsv->svl < 20) | ||
5130 | return (E_TRANSMIT_FORWARD_INVALID); | ||
5131 | |||
5132 | if((rsv->svv[0] != 0) || (rsv->svv[1] != 0)) | ||
5133 | return (E_TRANSMIT_FORWARD_INVALID); | ||
5134 | } | ||
5135 | |||
5136 | return (POSITIVE_ACK); | ||
5137 | } | ||
5138 | |||
5139 | static int smctr_set_local_ring_num(struct net_device *dev, | ||
5140 | MAC_SUB_VECTOR *rsv) | ||
5141 | { | ||
5142 | struct net_local *tp = netdev_priv(dev); | ||
5143 | |||
5144 | if(rsv->svl != S_LOCAL_RING_NUMBER) | ||
5145 | return (E_SUB_VECTOR_LENGTH_ERROR); | ||
5146 | |||
5147 | if(tp->ptr_local_ring_num) | ||
5148 | *(__u16 *)(tp->ptr_local_ring_num) | ||
5149 | = (rsv->svv[0] << 8 | rsv->svv[1]); | ||
5150 | |||
5151 | return (POSITIVE_ACK); | ||
5152 | } | ||
5153 | |||
5154 | static unsigned short smctr_set_ctrl_attention(struct net_device *dev) | ||
5155 | { | ||
5156 | struct net_local *tp = netdev_priv(dev); | ||
5157 | int ioaddr = dev->base_addr; | ||
5158 | |||
5159 | if(tp->bic_type == BIC_585_CHIP) | ||
5160 | outb((tp->trc_mask | HWR_CA), ioaddr + HWR); | ||
5161 | else | ||
5162 | { | ||
5163 | outb((tp->trc_mask | CSR_CA), ioaddr + CSR); | ||
5164 | outb(tp->trc_mask, ioaddr + CSR); | ||
5165 | } | ||
5166 | |||
5167 | return (0); | ||
5168 | } | ||
5169 | |||
5170 | static void smctr_set_multicast_list(struct net_device *dev) | ||
5171 | { | ||
5172 | if(smctr_debug > 10) | ||
5173 | printk(KERN_DEBUG "%s: smctr_set_multicast_list\n", dev->name); | ||
5174 | |||
5175 | return; | ||
5176 | } | ||
5177 | |||
5178 | static int smctr_set_page(struct net_device *dev, __u8 *buf) | ||
5179 | { | ||
5180 | struct net_local *tp = netdev_priv(dev); | ||
5181 | __u8 amask; | ||
5182 | __u32 tptr; | ||
5183 | |||
5184 | tptr = (__u32)buf - (__u32)tp->ram_access; | ||
5185 | amask = (__u8)((tptr & PR_PAGE_MASK) >> 8); | ||
5186 | outb(amask, dev->base_addr + PR); | ||
5187 | |||
5188 | return (0); | ||
5189 | } | ||
5190 | |||
5191 | static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv) | ||
5192 | { | ||
5193 | int err; | ||
5194 | |||
5195 | if(rsv->svl != S_PHYSICAL_DROP) | ||
5196 | return (E_SUB_VECTOR_LENGTH_ERROR); | ||
5197 | |||
5198 | smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]); | ||
5199 | if((err = smctr_wait_cmd(dev))) | ||
5200 | return (err); | ||
5201 | |||
5202 | return (POSITIVE_ACK); | ||
5203 | } | ||
5204 | |||
5205 | /* Reset the ring speed to the opposite of what it was. This auto-pilot | ||
5206 | * mode requires a complete reset and re-init of the adapter. | ||
5207 | */ | ||
5208 | static int smctr_set_ring_speed(struct net_device *dev) | ||
5209 | { | ||
5210 | struct net_local *tp = netdev_priv(dev); | ||
5211 | int err; | ||
5212 | |||
5213 | if(tp->media_type == MEDIA_UTP_16) | ||
5214 | tp->media_type = MEDIA_UTP_4; | ||
5215 | else | ||
5216 | tp->media_type = MEDIA_UTP_16; | ||
5217 | |||
5218 | smctr_enable_16bit(dev); | ||
5219 | |||
5220 | /* Re-Initialize adapter's internal registers */ | ||
5221 | smctr_reset_adapter(dev); | ||
5222 | |||
5223 | if((err = smctr_init_card_real(dev))) | ||
5224 | return (err); | ||
5225 | |||
5226 | smctr_enable_bic_int(dev); | ||
5227 | |||
5228 | if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) | ||
5229 | return (err); | ||
5230 | |||
5231 | smctr_disable_16bit(dev); | ||
5232 | |||
5233 | return (0); | ||
5234 | } | ||
5235 | |||
5236 | static int smctr_set_rx_look_ahead(struct net_device *dev) | ||
5237 | { | ||
5238 | struct net_local *tp = netdev_priv(dev); | ||
5239 | __u16 sword, rword; | ||
5240 | |||
5241 | if(smctr_debug > 10) | ||
5242 | printk(KERN_DEBUG "%s: smctr_set_rx_look_ahead_flag\n", dev->name); | ||
5243 | |||
5244 | tp->adapter_flags &= ~(FORCED_16BIT_MODE); | ||
5245 | tp->adapter_flags |= RX_VALID_LOOKAHEAD; | ||
5246 | |||
5247 | if(tp->adapter_bus == BUS_ISA16_TYPE) | ||
5248 | { | ||
5249 | sword = *((__u16 *)(tp->ram_access)); | ||
5250 | *((__u16 *)(tp->ram_access)) = 0x1234; | ||
5251 | |||
5252 | smctr_disable_16bit(dev); | ||
5253 | rword = *((__u16 *)(tp->ram_access)); | ||
5254 | smctr_enable_16bit(dev); | ||
5255 | |||
5256 | if(rword != 0x1234) | ||
5257 | tp->adapter_flags |= FORCED_16BIT_MODE; | ||
5258 | |||
5259 | *((__u16 *)(tp->ram_access)) = sword; | ||
5260 | } | ||
5261 | |||
5262 | return (0); | ||
5263 | } | ||
5264 | |||
5265 | static int smctr_set_trc_reset(int ioaddr) | ||
5266 | { | ||
5267 | __u8 r; | ||
5268 | |||
5269 | r = inb(ioaddr + MSR); | ||
5270 | outb(MSR_RST | r, ioaddr + MSR); | ||
5271 | |||
5272 | return (0); | ||
5273 | } | ||
5274 | |||
5275 | /* | ||
5276 | * This function can be called if the adapter is busy or not. | ||
5277 | */ | ||
5278 | static int smctr_setup_single_cmd(struct net_device *dev, | ||
5279 | __u16 command, __u16 subcommand) | ||
5280 | { | ||
5281 | struct net_local *tp = netdev_priv(dev); | ||
5282 | unsigned int err; | ||
5283 | |||
5284 | if(smctr_debug > 10) | ||
5285 | printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name); | ||
5286 | |||
5287 | if((err = smctr_wait_while_cbusy(dev))) | ||
5288 | return (err); | ||
5289 | |||
5290 | if((err = (unsigned int)smctr_wait_cmd(dev))) | ||
5291 | return (err); | ||
5292 | |||
5293 | tp->acb_head->cmd_done_status = 0; | ||
5294 | tp->acb_head->cmd = command; | ||
5295 | tp->acb_head->subcmd = subcommand; | ||
5296 | |||
5297 | err = smctr_issue_resume_acb_cmd(dev); | ||
5298 | |||
5299 | return (err); | ||
5300 | } | ||
5301 | |||
5302 | /* | ||
5303 | * This function can not be called with the adapter busy. | ||
5304 | */ | ||
5305 | static int smctr_setup_single_cmd_w_data(struct net_device *dev, | ||
5306 | __u16 command, __u16 subcommand) | ||
5307 | { | ||
5308 | struct net_local *tp = netdev_priv(dev); | ||
5309 | |||
5310 | tp->acb_head->cmd_done_status = ACB_COMMAND_NOT_DONE; | ||
5311 | tp->acb_head->cmd = command; | ||
5312 | tp->acb_head->subcmd = subcommand; | ||
5313 | tp->acb_head->data_offset_lo | ||
5314 | = (__u16)TRC_POINTER(tp->misc_command_data); | ||
5315 | |||
5316 | return(smctr_issue_resume_acb_cmd(dev)); | ||
5317 | } | ||
5318 | |||
5319 | static char *smctr_malloc(struct net_device *dev, __u16 size) | ||
5320 | { | ||
5321 | struct net_local *tp = netdev_priv(dev); | ||
5322 | char *m; | ||
5323 | |||
5324 | m = (char *)(tp->ram_access + tp->sh_mem_used); | ||
5325 | tp->sh_mem_used += (__u32)size; | ||
5326 | |||
5327 | return (m); | ||
5328 | } | ||
5329 | |||
5330 | static int smctr_status_chg(struct net_device *dev) | ||
5331 | { | ||
5332 | struct net_local *tp = netdev_priv(dev); | ||
5333 | |||
5334 | if(smctr_debug > 10) | ||
5335 | printk(KERN_DEBUG "%s: smctr_status_chg\n", dev->name); | ||
5336 | |||
5337 | switch(tp->status) | ||
5338 | { | ||
5339 | case OPEN: | ||
5340 | break; | ||
5341 | |||
5342 | case CLOSED: | ||
5343 | break; | ||
5344 | |||
5345 | /* Interrupt driven open() completion. XXX */ | ||
5346 | case INITIALIZED: | ||
5347 | tp->group_address_0 = 0; | ||
5348 | tp->group_address[0] = 0; | ||
5349 | tp->group_address[1] = 0; | ||
5350 | tp->functional_address_0 = 0; | ||
5351 | tp->functional_address[0] = 0; | ||
5352 | tp->functional_address[1] = 0; | ||
5353 | smctr_open_tr(dev); | ||
5354 | break; | ||
5355 | |||
5356 | default: | ||
5357 | printk(KERN_INFO "%s: status change unknown %x\n", | ||
5358 | dev->name, tp->status); | ||
5359 | break; | ||
5360 | } | ||
5361 | |||
5362 | return (0); | ||
5363 | } | ||
5364 | |||
5365 | static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, | ||
5366 | __u16 queue) | ||
5367 | { | ||
5368 | struct net_local *tp = netdev_priv(dev); | ||
5369 | int err = 0; | ||
5370 | |||
5371 | if(smctr_debug > 10) | ||
5372 | printk(KERN_DEBUG "%s: smctr_trc_send_packet\n", dev->name); | ||
5373 | |||
5374 | fcb->info = FCB_CHAIN_END | FCB_ENABLE_TFS; | ||
5375 | if(tp->num_tx_fcbs[queue] != 1) | ||
5376 | fcb->back_ptr->info = FCB_INTERRUPT_ENABLE | FCB_ENABLE_TFS; | ||
5377 | |||
5378 | if(tp->tx_queue_status[queue] == NOT_TRANSMITING) | ||
5379 | { | ||
5380 | tp->tx_queue_status[queue] = TRANSMITING; | ||
5381 | err = smctr_issue_resume_tx_fcb_cmd(dev, queue); | ||
5382 | } | ||
5383 | |||
5384 | return (err); | ||
5385 | } | ||
5386 | |||
5387 | static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) | ||
5388 | { | ||
5389 | struct net_local *tp = netdev_priv(dev); | ||
5390 | __u16 status, err = 0; | ||
5391 | int cstatus; | ||
5392 | |||
5393 | if(smctr_debug > 10) | ||
5394 | printk(KERN_DEBUG "%s: smctr_tx_complete\n", dev->name); | ||
5395 | |||
5396 | while((status = tp->tx_fcb_end[queue]->frame_status) != SUCCESS) | ||
5397 | { | ||
5398 | if(status & 0x7e00 ) | ||
5399 | { | ||
5400 | err = HARDWARE_FAILED; | ||
5401 | break; | ||
5402 | } | ||
5403 | |||
5404 | if((err = smctr_update_tx_chain(dev, tp->tx_fcb_end[queue], | ||
5405 | queue)) != SUCCESS) | ||
5406 | break; | ||
5407 | |||
5408 | smctr_disable_16bit(dev); | ||
5409 | |||
5410 | if(tp->mode_bits & UMAC) | ||
5411 | { | ||
5412 | if(!(status & (FCB_TX_STATUS_AR1 | FCB_TX_STATUS_AR2))) | ||
5413 | cstatus = NO_SUCH_DESTINATION; | ||
5414 | else | ||
5415 | { | ||
5416 | if(!(status & (FCB_TX_STATUS_CR1 | FCB_TX_STATUS_CR2))) | ||
5417 | cstatus = DEST_OUT_OF_RESOURCES; | ||
5418 | else | ||
5419 | { | ||
5420 | if(status & FCB_TX_STATUS_E) | ||
5421 | cstatus = MAX_COLLISIONS; | ||
5422 | else | ||
5423 | cstatus = SUCCESS; | ||
5424 | } | ||
5425 | } | ||
5426 | } | ||
5427 | else | ||
5428 | cstatus = SUCCESS; | ||
5429 | |||
5430 | if(queue == BUG_QUEUE) | ||
5431 | err = SUCCESS; | ||
5432 | |||
5433 | smctr_enable_16bit(dev); | ||
5434 | if(err != SUCCESS) | ||
5435 | break; | ||
5436 | } | ||
5437 | |||
5438 | return (err); | ||
5439 | } | ||
5440 | |||
5441 | static unsigned short smctr_tx_move_frame(struct net_device *dev, | ||
5442 | struct sk_buff *skb, __u8 *pbuff, unsigned int bytes) | ||
5443 | { | ||
5444 | struct net_local *tp = netdev_priv(dev); | ||
5445 | unsigned int ram_usable; | ||
5446 | __u32 flen, len, offset = 0; | ||
5447 | __u8 *frag, *page; | ||
5448 | |||
5449 | if(smctr_debug > 10) | ||
5450 | printk(KERN_DEBUG "%s: smctr_tx_move_frame\n", dev->name); | ||
5451 | |||
5452 | ram_usable = ((unsigned int)tp->ram_usable) << 10; | ||
5453 | frag = skb->data; | ||
5454 | flen = skb->len; | ||
5455 | |||
5456 | while(flen > 0 && bytes > 0) | ||
5457 | { | ||
5458 | smctr_set_page(dev, pbuff); | ||
5459 | |||
5460 | offset = SMC_PAGE_OFFSET(pbuff); | ||
5461 | |||
5462 | if(offset + flen > ram_usable) | ||
5463 | len = ram_usable - offset; | ||
5464 | else | ||
5465 | len = flen; | ||
5466 | |||
5467 | if(len > bytes) | ||
5468 | len = bytes; | ||
5469 | |||
5470 | page = (char *) (offset + tp->ram_access); | ||
5471 | memcpy(page, frag, len); | ||
5472 | |||
5473 | flen -=len; | ||
5474 | bytes -= len; | ||
5475 | frag += len; | ||
5476 | pbuff += len; | ||
5477 | } | ||
5478 | |||
5479 | return (0); | ||
5480 | } | ||
5481 | |||
5482 | /* Update the error statistic counters for this adapter. */ | ||
5483 | static int smctr_update_err_stats(struct net_device *dev) | ||
5484 | { | ||
5485 | struct net_local *tp = netdev_priv(dev); | ||
5486 | struct tr_statistics *tstat = &tp->MacStat; | ||
5487 | |||
5488 | if(tstat->internal_errors) | ||
5489 | tstat->internal_errors | ||
5490 | += *(tp->misc_command_data + 0) & 0x00ff; | ||
5491 | |||
5492 | if(tstat->line_errors) | ||
5493 | tstat->line_errors += *(tp->misc_command_data + 0) >> 8; | ||
5494 | |||
5495 | if(tstat->A_C_errors) | ||
5496 | tstat->A_C_errors += *(tp->misc_command_data + 1) & 0x00ff; | ||
5497 | |||
5498 | if(tstat->burst_errors) | ||
5499 | tstat->burst_errors += *(tp->misc_command_data + 1) >> 8; | ||
5500 | |||
5501 | if(tstat->abort_delimiters) | ||
5502 | tstat->abort_delimiters += *(tp->misc_command_data + 2) >> 8; | ||
5503 | |||
5504 | if(tstat->recv_congest_count) | ||
5505 | tstat->recv_congest_count | ||
5506 | += *(tp->misc_command_data + 3) & 0x00ff; | ||
5507 | |||
5508 | if(tstat->lost_frames) | ||
5509 | tstat->lost_frames | ||
5510 | += *(tp->misc_command_data + 3) >> 8; | ||
5511 | |||
5512 | if(tstat->frequency_errors) | ||
5513 | tstat->frequency_errors += *(tp->misc_command_data + 4) & 0x00ff; | ||
5514 | |||
5515 | if(tstat->frame_copied_errors) | ||
5516 | tstat->frame_copied_errors | ||
5517 | += *(tp->misc_command_data + 4) >> 8; | ||
5518 | |||
5519 | if(tstat->token_errors) | ||
5520 | tstat->token_errors += *(tp->misc_command_data + 5) >> 8; | ||
5521 | |||
5522 | return (0); | ||
5523 | } | ||
5524 | |||
5525 | static int smctr_update_rx_chain(struct net_device *dev, __u16 queue) | ||
5526 | { | ||
5527 | struct net_local *tp = netdev_priv(dev); | ||
5528 | FCBlock *fcb; | ||
5529 | BDBlock *bdb; | ||
5530 | __u16 size, len; | ||
5531 | |||
5532 | fcb = tp->rx_fcb_curr[queue]; | ||
5533 | len = fcb->frame_length; | ||
5534 | |||
5535 | fcb->frame_status = 0; | ||
5536 | fcb->info = FCB_CHAIN_END; | ||
5537 | fcb->back_ptr->info = FCB_WARNING; | ||
5538 | |||
5539 | tp->rx_fcb_curr[queue] = tp->rx_fcb_curr[queue]->next_ptr; | ||
5540 | |||
5541 | /* update RX BDBs */ | ||
5542 | size = (len >> RX_BDB_SIZE_SHIFT); | ||
5543 | if(len & RX_DATA_BUFFER_SIZE_MASK) | ||
5544 | size += sizeof(BDBlock); | ||
5545 | size &= (~RX_BDB_SIZE_MASK); | ||
5546 | |||
5547 | /* check if wrap around */ | ||
5548 | bdb = (BDBlock *)((__u32)(tp->rx_bdb_curr[queue]) + (__u32)(size)); | ||
5549 | if((__u32)bdb >= (__u32)tp->rx_bdb_end[queue]) | ||
5550 | { | ||
5551 | bdb = (BDBlock *)((__u32)(tp->rx_bdb_head[queue]) | ||
5552 | + (__u32)(bdb) - (__u32)(tp->rx_bdb_end[queue])); | ||
5553 | } | ||
5554 | |||
5555 | bdb->back_ptr->info = BDB_CHAIN_END; | ||
5556 | tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END; | ||
5557 | tp->rx_bdb_curr[queue] = bdb; | ||
5558 | |||
5559 | return (0); | ||
5560 | } | ||
5561 | |||
5562 | static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, | ||
5563 | __u16 queue) | ||
5564 | { | ||
5565 | struct net_local *tp = netdev_priv(dev); | ||
5566 | |||
5567 | if(smctr_debug > 20) | ||
5568 | printk(KERN_DEBUG "smctr_update_tx_chain\n"); | ||
5569 | |||
5570 | if(tp->num_tx_fcbs_used[queue] <= 0) | ||
5571 | return (HARDWARE_FAILED); | ||
5572 | else | ||
5573 | { | ||
5574 | if(tp->tx_buff_used[queue] < fcb->memory_alloc) | ||
5575 | { | ||
5576 | tp->tx_buff_used[queue] = 0; | ||
5577 | return (HARDWARE_FAILED); | ||
5578 | } | ||
5579 | |||
5580 | tp->tx_buff_used[queue] -= fcb->memory_alloc; | ||
5581 | |||
5582 | /* if all transmit buffer are cleared | ||
5583 | * need to set the tx_buff_curr[] to tx_buff_head[] | ||
5584 | * otherwise, tx buffer will be segregate and cannot | ||
5585 | * accommodate and buffer greater than (curr - head) and | ||
5586 | * (end - curr) since we do not allow wrap around allocation. | ||
5587 | */ | ||
5588 | if(tp->tx_buff_used[queue] == 0) | ||
5589 | tp->tx_buff_curr[queue] = tp->tx_buff_head[queue]; | ||
5590 | |||
5591 | tp->num_tx_fcbs_used[queue]--; | ||
5592 | fcb->frame_status = 0; | ||
5593 | tp->tx_fcb_end[queue] = fcb->next_ptr; | ||
5594 | netif_wake_queue(dev); | ||
5595 | return (0); | ||
5596 | } | ||
5597 | } | ||
5598 | |||
5599 | static int smctr_wait_cmd(struct net_device *dev) | ||
5600 | { | ||
5601 | struct net_local *tp = netdev_priv(dev); | ||
5602 | unsigned int loop_count = 0x20000; | ||
5603 | |||
5604 | if(smctr_debug > 10) | ||
5605 | printk(KERN_DEBUG "%s: smctr_wait_cmd\n", dev->name); | ||
5606 | |||
5607 | while(loop_count) | ||
5608 | { | ||
5609 | if(tp->acb_head->cmd_done_status & ACB_COMMAND_DONE) | ||
5610 | break; | ||
5611 | udelay(1); | ||
5612 | loop_count--; | ||
5613 | } | ||
5614 | |||
5615 | if(loop_count == 0) | ||
5616 | return(HARDWARE_FAILED); | ||
5617 | |||
5618 | if(tp->acb_head->cmd_done_status & 0xff) | ||
5619 | return(HARDWARE_FAILED); | ||
5620 | |||
5621 | return (0); | ||
5622 | } | ||
5623 | |||
5624 | static int smctr_wait_while_cbusy(struct net_device *dev) | ||
5625 | { | ||
5626 | struct net_local *tp = netdev_priv(dev); | ||
5627 | unsigned int timeout = 0x20000; | ||
5628 | int ioaddr = dev->base_addr; | ||
5629 | __u8 r; | ||
5630 | |||
5631 | if(tp->bic_type == BIC_585_CHIP) | ||
5632 | { | ||
5633 | while(timeout) | ||
5634 | { | ||
5635 | r = inb(ioaddr + HWR); | ||
5636 | if((r & HWR_CBUSY) == 0) | ||
5637 | break; | ||
5638 | timeout--; | ||
5639 | } | ||
5640 | } | ||
5641 | else | ||
5642 | { | ||
5643 | while(timeout) | ||
5644 | { | ||
5645 | r = inb(ioaddr + CSR); | ||
5646 | if((r & CSR_CBUSY) == 0) | ||
5647 | break; | ||
5648 | timeout--; | ||
5649 | } | ||
5650 | } | ||
5651 | |||
5652 | if(timeout) | ||
5653 | return (0); | ||
5654 | else | ||
5655 | return (HARDWARE_FAILED); | ||
5656 | } | ||
5657 | |||
5658 | #ifdef MODULE | ||
5659 | |||
5660 | static struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS]; | ||
5661 | static int io[SMCTR_MAX_ADAPTERS]; | ||
5662 | static int irq[SMCTR_MAX_ADAPTERS]; | ||
5663 | |||
5664 | MODULE_LICENSE("GPL"); | ||
5665 | |||
5666 | module_param_array(io, int, NULL, 0); | ||
5667 | module_param_array(irq, int, NULL, 0); | ||
5668 | module_param(ringspeed, int, 0); | ||
5669 | |||
5670 | static struct net_device *setup_card(int n) | ||
5671 | { | ||
5672 | struct net_device *dev = alloc_trdev(sizeof(struct net_local)); | ||
5673 | int err; | ||
5674 | |||
5675 | if (!dev) | ||
5676 | return ERR_PTR(-ENOMEM); | ||
5677 | |||
5678 | dev->irq = irq[n]; | ||
5679 | err = smctr_probe1(dev, io[n]); | ||
5680 | if (err) | ||
5681 | goto out; | ||
5682 | |||
5683 | err = register_netdev(dev); | ||
5684 | if (err) | ||
5685 | goto out1; | ||
5686 | return dev; | ||
5687 | out1: | ||
5688 | #ifdef CONFIG_MCA_LEGACY | ||
5689 | { struct net_local *tp = netdev_priv(dev); | ||
5690 | if (tp->slot_num) | ||
5691 | mca_mark_as_unused(tp->slot_num); | ||
5692 | } | ||
5693 | #endif | ||
5694 | release_region(dev->base_addr, SMCTR_IO_EXTENT); | ||
5695 | free_irq(dev->irq, dev); | ||
5696 | out: | ||
5697 | free_netdev(dev); | ||
5698 | return ERR_PTR(err); | ||
5699 | } | ||
5700 | |||
5701 | |||
5702 | int init_module(void) | ||
5703 | { | ||
5704 | int i, found = 0; | ||
5705 | struct net_device *dev; | ||
5706 | |||
5707 | for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) { | ||
5708 | dev = io[0]? setup_card(i) : smctr_probe(-1); | ||
5709 | if (!IS_ERR(dev)) { | ||
5710 | ++found; | ||
5711 | dev_smctr[i] = dev; | ||
5712 | } | ||
5713 | } | ||
5714 | |||
5715 | return found ? 0 : -ENODEV; | ||
5716 | } | ||
5717 | |||
5718 | void cleanup_module(void) | ||
5719 | { | ||
5720 | int i; | ||
5721 | |||
5722 | for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) { | ||
5723 | struct net_device *dev = dev_smctr[i]; | ||
5724 | |||
5725 | if (dev) { | ||
5726 | |||
5727 | unregister_netdev(dev); | ||
5728 | #ifdef CONFIG_MCA_LEGACY | ||
5729 | { struct net_local *tp = netdev_priv(dev); | ||
5730 | if (tp->slot_num) | ||
5731 | mca_mark_as_unused(tp->slot_num); | ||
5732 | } | ||
5733 | #endif | ||
5734 | release_region(dev->base_addr, SMCTR_IO_EXTENT); | ||
5735 | if (dev->irq) | ||
5736 | free_irq(dev->irq, dev); | ||
5737 | |||
5738 | free_netdev(dev); | ||
5739 | } | ||
5740 | } | ||
5741 | } | ||
5742 | #endif /* MODULE */ | ||