This source file includes following definitions.
- znet_probe
- znet_open
- znet_send_packet
- znet_interrupt
- znet_rx
- znet_close
- net_get_stats
- set_multicast_list
- show_dma
- hardware_init
- update_stop_hit
1
2
3 static char *version = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n";
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 #include <linux/config.h>
66 #include <linux/kernel.h>
67 #include <linux/sched.h>
68 #include <linux/string.h>
69 #include <linux/ptrace.h>
70 #include <linux/errno.h>
71 #include <linux/interrupt.h>
72 #include <linux/ioport.h>
73 #include <asm/system.h>
74 #include <asm/bitops.h>
75 #include <asm/io.h>
76 #include <asm/dma.h>
77
78 #include <linux/netdevice.h>
79 #include <linux/etherdevice.h>
80 #include <linux/skbuff.h>
81 #include <linux/if_arp.h>
82
83 #ifndef ZNET_DEBUG
84 #define ZNET_DEBUG 1
85 #endif
86 static unsigned int znet_debug = ZNET_DEBUG;
87
88
89 #define DMA_RX_MODE 0x14
90 #define DMA_TX_MODE 0x18
91 #define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
92 #define DMA_BUF_SIZE 8192
93 #define RX_BUF_SIZE 8192
94 #define TX_BUF_SIZE 8192
95
96
97 #define CMD0_CHNL_0 0x00
98 #define CMD0_CHNL_1 0x10
99 #define CMD0_NOP (CMD0_CHNL_0)
100 #define CMD0_PORT_1 CMD0_CHNL_1
101 #define CMD1_PORT_0 1
102 #define CMD0_IA_SETUP 1
103 #define CMD0_CONFIGURE 2
104 #define CMD0_MULTICAST_LIST 3
105 #define CMD0_TRANSMIT 4
106 #define CMD0_DUMP 6
107 #define CMD0_DIAGNOSE 7
108 #define CMD0_Rx_ENABLE 8
109 #define CMD0_Rx_DISABLE 10
110 #define CMD0_Rx_STOP 11
111 #define CMD0_RETRANSMIT 12
112 #define CMD0_ABORT 13
113 #define CMD0_RESET 14
114
115 #define CMD0_ACK 0x80
116
117 #define CMD0_STAT0 (0 << 5)
118 #define CMD0_STAT1 (1 << 5)
119 #define CMD0_STAT2 (2 << 5)
120 #define CMD0_STAT3 (3 << 5)
121
122 #define net_local znet_private
123 struct znet_private {
124 int rx_dma, tx_dma;
125 struct enet_statistics stats;
126
127 ushort *rx_start, *rx_cur, *rx_end;
128 ushort *tx_start, *tx_cur, *tx_end;
129 ushort tx_buf_len;
130 };
131
132
133 static struct znet_private zn;
134 static ushort dma_buffer1[DMA_BUF_SIZE/2];
135 static ushort dma_buffer2[DMA_BUF_SIZE/2];
136 static ushort dma_buffer3[DMA_BUF_SIZE/2 + 8];
137
138
139
140
141
142
143
144 static unsigned char i593_init[] = {
145 0xAA,
146
147 0x88,
148 0x2E,
149
150 0x00,
151 0x60,
152 0x00,
153 0xF2,
154 0x00,
155 0x00,
156 0x40,
157 0x5F,
158
159 0x00,
160 0x3F,
161 0x07,
162 0x31,
163
164 0x22,
165
166 };
167
168 struct netidblk {
169 char magic[8];
170 unsigned char netid[8];
171 char nettype, globalopt;
172 char vendor[8];
173 char product[8];
174 char irq1, irq2;
175 char dma1, dma2;
176 short dma_mem_misc[8];
177 short iobase1, iosize1;
178 short iobase2, iosize2;
179 char driver_options;
180 char pad;
181 };
182
183 int znet_probe(struct device *dev);
184 static int znet_open(struct device *dev);
185 static int znet_send_packet(struct sk_buff *skb, struct device *dev);
186 static void znet_interrupt(int reg_ptr);
187 static void znet_rx(struct device *dev);
188 static int znet_close(struct device *dev);
189 static struct enet_statistics *net_get_stats(struct device *dev);
190 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
191 static void hardware_init(struct device *dev);
192 static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset);
193
194 #ifdef notdef
195 static struct sigaction znet_sigaction = { &znet_interrupt, 0, 0, NULL, };
196 #endif
197
198
199
200
201
202
203 int znet_probe(struct device *dev)
204 {
205 int i;
206 struct netidblk *netinfo;
207 char *p;
208
209
210 for(p = (char *)0xf0000; p < (char *)0x100000; p++)
211 if (*p == 'N' && strncmp(p, "NETIDBLK", 8) == 0)
212 break;
213
214 if (p >= (char *)0x100000) {
215 if (znet_debug > 1)
216 printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");
217 return ENODEV;
218 }
219 netinfo = (struct netidblk *)p;
220 dev->base_addr = netinfo->iobase1;
221 dev->irq = netinfo->irq1;
222
223 printk(KERN_INFO "%s: ZNET at %#3x,", dev->name, dev->base_addr);
224
225
226 for (i = 0; i < 6; i++)
227 printk(" %2.2x", dev->dev_addr[i] = netinfo->netid[i]);
228
229 printk(", using IRQ %d DMA %d and %d.\n", dev->irq, netinfo->dma1,
230 netinfo->dma2);
231
232 if (znet_debug > 1) {
233 printk(KERN_INFO "%s: vendor '%16.16s' IRQ1 %d IRQ2 %d DMA1 %d DMA2 %d.\n",
234 dev->name, netinfo->vendor,
235 netinfo->irq1, netinfo->irq2,
236 netinfo->dma1, netinfo->dma2);
237 printk(KERN_INFO "%s: iobase1 %#x size %d iobase2 %#x size %d net type %2.2x.\n",
238 dev->name, netinfo->iobase1, netinfo->iosize1,
239 netinfo->iobase2, netinfo->iosize2, netinfo->nettype);
240 }
241
242 if (znet_debug > 0)
243 printk("%s%s", KERN_INFO, version);
244
245 dev->priv = (void *) &zn;
246 zn.rx_dma = netinfo->dma1;
247 zn.tx_dma = netinfo->dma2;
248
249
250 if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet")
251 || request_dma(zn.rx_dma,"ZNet rx")
252 || request_dma(zn.tx_dma,"ZNet tx")) {
253 printk(KERN_WARNING "%s: Not opened -- resource busy?!?\n", dev->name);
254 return EBUSY;
255 }
256 irq2dev_map[dev->irq] = dev;
257
258
259
260 if (dma_page_eq(dma_buffer1, &dma_buffer1[RX_BUF_SIZE/2-1]))
261 zn.rx_start = dma_buffer1;
262 else
263 zn.rx_start = dma_buffer2;
264
265 if (dma_page_eq(dma_buffer3, &dma_buffer3[RX_BUF_SIZE/2-1]))
266 zn.tx_start = dma_buffer3;
267 else
268 zn.tx_start = dma_buffer2;
269 zn.rx_end = zn.rx_start + RX_BUF_SIZE/2;
270 zn.tx_buf_len = TX_BUF_SIZE/2;
271 zn.tx_end = zn.tx_start + zn.tx_buf_len;
272
273
274 dev->open = &znet_open;
275 dev->hard_start_xmit = &znet_send_packet;
276 dev->stop = &znet_close;
277 dev->get_stats = net_get_stats;
278 dev->set_multicast_list = &set_multicast_list;
279
280
281 ether_setup(dev);
282
283 return 0;
284 }
285
286
287 static int znet_open(struct device *dev)
288 {
289 int ioaddr = dev->base_addr;
290
291 if (znet_debug > 2)
292 printk(KERN_DEBUG "%s: znet_open() called.\n", dev->name);
293
294
295 outb(0x10, 0xe6);
296 outb(inb(0xe7) | 0x84, 0xe7);
297
298
299
300
301
302
303
304
305
306 if (inb(ioaddr) != 0x10 && inb(ioaddr) != 0x00)
307 printk(KERN_WARNING "%s: Problem turning on the transceiver power.\n",
308 dev->name);
309
310 dev->tbusy = 0;
311 dev->interrupt = 0;
312 hardware_init(dev);
313 dev->start = 1;
314
315 return 0;
316 }
317
318 static int znet_send_packet(struct sk_buff *skb, struct device *dev)
319 {
320 int ioaddr = dev->base_addr;
321
322 if (znet_debug > 4)
323 printk(KERN_DEBUG "%s: ZNet_send_packet(%d).\n", dev->name, dev->tbusy);
324
325
326 if (dev->tbusy) {
327 ushort event, tx_status, rx_offset, state;
328 int tickssofar = jiffies - dev->trans_start;
329 if (tickssofar < 10)
330 return 1;
331 outb(CMD0_STAT0, ioaddr); event = inb(ioaddr);
332 outb(CMD0_STAT1, ioaddr); tx_status = inw(ioaddr);
333 outb(CMD0_STAT2, ioaddr); rx_offset = inw(ioaddr);
334 outb(CMD0_STAT3, ioaddr); state = inb(ioaddr);
335 printk(KERN_WARNING "%s: transmit timed out, status %02x %04x %04x %02x,"
336 " resetting.\n", dev->name, event, tx_status, rx_offset, state);
337 if (tx_status == 0x0400)
338 printk(KERN_WARNING "%s: Tx carrier error, check transceiver cable.\n",
339 dev->name);
340 outb(CMD0_RESET, ioaddr);
341 hardware_init(dev);
342 }
343
344 if (skb == NULL) {
345 dev_tint(dev);
346 return 0;
347 }
348
349
350 outb(CMD0_STAT0, ioaddr);
351 if (inw(ioaddr) == 0x0010
352 && inw(ioaddr) == 0x0000
353 && inw(ioaddr) == 0x0010)
354 hardware_init(dev);
355
356
357
358 if (set_bit(0, (void*)&dev->tbusy) != 0)
359 printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
360 else {
361 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
362 unsigned char *buf = (void *)(skb+1);
363 ushort *tx_link = zn.tx_cur - 1;
364 ushort rnd_len = (length + 1)>>1;
365
366 {
367 short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
368 unsigned addr = inb(dma_port);
369 addr |= inb(dma_port) << 8;
370 addr <<= 1;
371 if (((int)zn.tx_cur & 0x1ffff) != addr)
372 printk(KERN_WARNING "Address mismatch at Tx: %#x vs %#x.\n",
373 (int)zn.tx_cur & 0xffff, addr);
374 zn.tx_cur = (ushort *)(((int)zn.tx_cur & 0xfe0000) | addr);
375 }
376
377 if (zn.tx_cur >= zn.tx_end)
378 zn.tx_cur = zn.tx_start;
379 *zn.tx_cur++ = length;
380 if (zn.tx_cur + rnd_len + 1 > zn.tx_end) {
381 int semi_cnt = (zn.tx_end - zn.tx_cur)<<1;
382 memcpy(zn.tx_cur, buf, semi_cnt);
383 rnd_len -= semi_cnt>>1;
384 memcpy(zn.tx_start, buf + semi_cnt, length - semi_cnt);
385 zn.tx_cur = zn.tx_start + rnd_len;
386 } else {
387 memcpy(zn.tx_cur, buf, skb->len);
388 zn.tx_cur += rnd_len;
389 }
390 *zn.tx_cur++ = 0;
391 cli(); {
392 *tx_link = CMD0_TRANSMIT + CMD0_CHNL_1;
393
394 outb(CMD0_TRANSMIT + CMD0_CHNL_1,ioaddr);
395 } sti();
396
397 dev->trans_start = jiffies;
398 if (znet_debug > 4)
399 printk(KERN_DEBUG "%s: Transmitter queued, length %d.\n", dev->name, length);
400 }
401 dev_kfree_skb(skb, FREE_WRITE);
402 return 0;
403 }
404
405
406 static void znet_interrupt(int reg_ptr)
407 {
408 int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
409 struct device *dev = irq2dev_map[irq];
410 int ioaddr;
411 int boguscnt = 20;
412
413 if (dev == NULL) {
414 printk(KERN_WARNING "znet_interrupt(): IRQ %d for unknown device.\n", irq);
415 return;
416 }
417
418 dev->interrupt = 1;
419 ioaddr = dev->base_addr;
420
421 outb(CMD0_STAT0, ioaddr);
422 do {
423 ushort status = inb(ioaddr);
424 if (znet_debug > 5) {
425 ushort result, rx_ptr, running;
426 outb(CMD0_STAT1, ioaddr);
427 result = inw(ioaddr);
428 outb(CMD0_STAT2, ioaddr);
429 rx_ptr = inw(ioaddr);
430 outb(CMD0_STAT3, ioaddr);
431 running = inb(ioaddr);
432 printk(KERN_DEBUG "%s: interrupt, status %02x, %04x %04x %02x serial %d.\n",
433 dev->name, status, result, rx_ptr, running, boguscnt);
434 }
435 if ((status & 0x80) == 0)
436 break;
437
438 if ((status & 0x0F) == 4) {
439 struct net_local *lp = (struct net_local *)dev->priv;
440 int tx_status;
441 outb(CMD0_STAT1, ioaddr);
442 tx_status = inw(ioaddr);
443
444 if (tx_status & 0x2000) {
445 lp->stats.tx_packets++;
446 lp->stats.collisions += tx_status & 0xf;
447 } else {
448 if (tx_status & 0x0600) lp->stats.tx_carrier_errors++;
449 if (tx_status & 0x0100) lp->stats.tx_fifo_errors++;
450 if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
451 if (tx_status & 0x0020) lp->stats.tx_aborted_errors++;
452
453 if (tx_status | 0x0760 != 0x0760)
454 lp->stats.tx_errors++;
455 }
456 dev->tbusy = 0;
457 mark_bh(NET_BH);
458 }
459
460 if ((status & 0x40)
461 || (status & 0x0f) == 11) {
462 znet_rx(dev);
463 }
464
465 outb(CMD0_ACK,ioaddr);
466 } while (boguscnt--);
467
468 dev->interrupt = 0;
469 return;
470 }
471
472 static void znet_rx(struct device *dev)
473 {
474 struct net_local *lp = (struct net_local *)dev->priv;
475 int ioaddr = dev->base_addr;
476 int boguscount = 1;
477 short next_frame_end_offset = 0;
478 short *cur_frame_end;
479 short cur_frame_end_offset;
480
481 outb(CMD0_STAT2, ioaddr);
482 cur_frame_end_offset = inw(ioaddr);
483
484 if (cur_frame_end_offset == zn.rx_cur - zn.rx_start) {
485 printk(KERN_WARNING "%s: Interrupted, but nothing to receive, offset %03x.\n",
486 dev->name, cur_frame_end_offset);
487 return;
488 }
489
490
491
492
493
494 while (zn.rx_start + cur_frame_end_offset != zn.rx_cur
495 && ++boguscount < 5) {
496 unsigned short hi_cnt, lo_cnt, hi_status, lo_status;
497 int count, status;
498
499 if (cur_frame_end_offset < 4) {
500
501
502
503 memcpy(zn.rx_end, zn.rx_start, 8);
504 cur_frame_end_offset += (RX_BUF_SIZE/2);
505 }
506 cur_frame_end = zn.rx_start + cur_frame_end_offset - 4;
507
508 lo_status = *cur_frame_end++;
509 hi_status = *cur_frame_end++;
510 status = ((hi_status & 0xff) << 8) + (lo_status & 0xff);
511 lo_cnt = *cur_frame_end++;
512 hi_cnt = *cur_frame_end++;
513 count = ((hi_cnt & 0xff) << 8) + (lo_cnt & 0xff);
514
515 if (znet_debug > 5)
516 printk(KERN_DEBUG "Constructing trailer at location %03x, %04x %04x %04x %04x"
517 " count %#x status %04x.\n",
518 cur_frame_end_offset<<1, lo_status, hi_status, lo_cnt, hi_cnt,
519 count, status);
520 cur_frame_end[-4] = status;
521 cur_frame_end[-3] = next_frame_end_offset;
522 cur_frame_end[-2] = count;
523 next_frame_end_offset = cur_frame_end_offset;
524 cur_frame_end_offset -= ((count + 1)>>1) + 3;
525 if (cur_frame_end_offset < 0)
526 cur_frame_end_offset += RX_BUF_SIZE/2;
527 };
528
529
530 do {
531 ushort *this_rfp_ptr = zn.rx_start + next_frame_end_offset;
532 int status = this_rfp_ptr[-4];
533 int pkt_len = this_rfp_ptr[-2];
534
535 if (znet_debug > 5)
536 printk(KERN_DEBUG "Looking at trailer ending at %04x status %04x length %03x"
537 " next %04x.\n", next_frame_end_offset<<1, status, pkt_len,
538 this_rfp_ptr[-3]<<1);
539
540 if ( ! (status & 0x2000)) {
541 lp->stats.rx_errors++;
542 if (status & 0x0800) lp->stats.rx_crc_errors++;
543 if (status & 0x0400) lp->stats.rx_frame_errors++;
544 if (status & 0x0200) lp->stats.rx_over_errors++;
545 if (status & 0x0100) lp->stats.rx_fifo_errors++;
546 if (status & 0x0080) lp->stats.rx_length_errors++;
547 } else if (pkt_len > 1536) {
548 lp->stats.rx_length_errors++;
549 } else {
550
551 struct sk_buff *skb;
552
553 skb = alloc_skb(pkt_len, GFP_ATOMIC);
554 if (skb == NULL) {
555 if (znet_debug)
556 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
557 lp->stats.rx_dropped++;
558 break;
559 }
560 skb->len = pkt_len;
561 skb->dev = dev;
562
563 if (&zn.rx_cur[(pkt_len+1)>>1] > zn.rx_end) {
564 int semi_cnt = (zn.rx_end - zn.rx_cur)<<1;
565 memcpy((unsigned char *) (skb + 1), zn.rx_cur, semi_cnt);
566 memcpy((unsigned char *) (skb + 1) + semi_cnt, zn.rx_start,
567 pkt_len - semi_cnt);
568 } else {
569 memcpy((unsigned char *) (skb + 1), zn.rx_cur, pkt_len);
570 if (znet_debug > 6) {
571 unsigned int *packet = (unsigned int *) (skb + 1);
572 printk(KERN_DEBUG "Packet data is %08x %08x %08x %08x.\n", packet[0],
573 packet[1], packet[2], packet[3]);
574 }
575 }
576
577 #ifdef HAVE_NETIF_RX
578 netif_rx(skb);
579 #else
580 skb->lock = 0;
581 if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
582 kfree_s(skb, sksize);
583 lp->stats.rx_dropped++;
584 break;
585 }
586 #endif
587 lp->stats.rx_packets++;
588 }
589 zn.rx_cur = this_rfp_ptr;
590 if (zn.rx_cur >= zn.rx_end)
591 zn.rx_cur -= RX_BUF_SIZE/2;
592 update_stop_hit(ioaddr, (zn.rx_cur - zn.rx_start)<<1);
593 next_frame_end_offset = this_rfp_ptr[-3];
594 if (next_frame_end_offset == 0)
595 break;
596 this_rfp_ptr = zn.rx_start + next_frame_end_offset;
597 } while (--boguscount);
598
599
600
601
602 return;
603 }
604
605
606 static int znet_close(struct device *dev)
607 {
608 int ioaddr = dev->base_addr;
609
610 dev->tbusy = 1;
611 dev->start = 0;
612
613 outb(CMD0_RESET, ioaddr);
614
615 disable_dma(zn.rx_dma);
616 disable_dma(zn.tx_dma);
617
618 free_irq(dev->irq);
619
620 if (znet_debug > 1)
621 printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
622
623 outb(0x10, 0xe6);
624 outb(inb(0xe7) & ~0x84, 0xe7);
625
626 return 0;
627 }
628
629
630
631 static struct enet_statistics *net_get_stats(struct device *dev)
632 {
633 struct net_local *lp = (struct net_local *)dev->priv;
634
635 return &lp->stats;
636 }
637
638 #ifdef HAVE_MULTICAST
639
640
641
642
643
644
645
646
647
648
649
650
651 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
652 {
653 short ioaddr = dev->base_addr;
654
655 if (num_addrs < 0) {
656
657 i593_init[7] &= ~3; i593_init[7] |= 1;
658 i593_init[13] &= ~8; i593_init[13] |= 8;
659 } else if (num_addrs > 0) {
660
661 i593_init[7] &= ~3; i593_init[7] |= 0;
662 i593_init[13] &= ~8; i593_init[13] |= 8;
663 } else {
664 i593_init[7] &= ~3; i593_init[7] |= 0;
665 i593_init[13] &= ~8; i593_init[13] |= 0;
666 }
667 *zn.tx_cur++ = sizeof(i593_init);
668 memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
669 zn.tx_cur += sizeof(i593_init)/2;
670 outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
671 #ifdef not_tested
672 if (num_addrs > 0) {
673 int addrs_len = 6*num_addrs;
674 *zn.tx_cur++ = addrs_len;
675 memcpy(zn.tx_cur, addrs, addrs_len);
676 outb(CMD0_MULTICAST_LIST+CMD0_CHNL_1, ioaddr);
677 zn.tx_cur += addrs_len>>1;
678 }
679 #endif
680 }
681 #endif
682
683 void show_dma(void)
684 {
685 short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
686 unsigned addr = inb(dma_port);
687 addr |= inb(dma_port) << 8;
688 printk("Addr: %04x cnt:%3x...", addr<<1, get_dma_residue(zn.tx_dma));
689 }
690
691
692
693 static void hardware_init(struct device *dev)
694 {
695 short ioaddr = dev->base_addr;
696
697 zn.rx_cur = zn.rx_start;
698 zn.tx_cur = zn.tx_start;
699
700
701 outb(CMD0_RESET, ioaddr);
702
703 cli(); {
704 disable_dma(zn.rx_dma);
705 clear_dma_ff(zn.rx_dma);
706 set_dma_mode(zn.rx_dma, DMA_RX_MODE);
707 set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
708 set_dma_count(zn.rx_dma, RX_BUF_SIZE);
709 enable_dma(zn.rx_dma);
710
711 disable_dma(zn.tx_dma);
712 clear_dma_ff(zn.tx_dma);
713 set_dma_mode(zn.tx_dma, DMA_TX_MODE);
714 set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
715 set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
716 enable_dma(zn.tx_dma);
717 } sti();
718
719 if (znet_debug > 1)
720 printk(KERN_DEBUG "%s: Initializing the i82593, tx buf %p... ", dev->name,
721 zn.tx_start);
722
723
724 *zn.tx_cur++ = 0;
725 *zn.tx_cur++ = 0;
726 printk("stat:%02x ", inb(ioaddr)); show_dma();
727 outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
728 *zn.tx_cur++ = sizeof(i593_init);
729 memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
730 zn.tx_cur += sizeof(i593_init)/2;
731 printk("stat:%02x ", inb(ioaddr)); show_dma();
732 outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
733 *zn.tx_cur++ = 6;
734 memcpy(zn.tx_cur, dev->dev_addr, 6);
735 zn.tx_cur += 3;
736 printk("stat:%02x ", inb(ioaddr)); show_dma();
737 outb(CMD0_IA_SETUP + CMD0_CHNL_1, ioaddr);
738 printk("stat:%02x ", inb(ioaddr)); show_dma();
739
740 update_stop_hit(ioaddr, 8192);
741 if (znet_debug > 1) printk("enabling Rx.\n");
742 outb(CMD0_Rx_ENABLE+CMD0_CHNL_0, ioaddr);
743 dev->tbusy = 0;
744 }
745
746 static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
747 {
748 outb(CMD0_PORT_1, ioaddr);
749 if (znet_debug > 5)
750 printk(KERN_DEBUG "Updating stop hit with value %02x.\n",
751 (rx_stop_offset >> 6) | 0x80);
752 outb((rx_stop_offset >> 6) | 0x80, ioaddr);
753 outb(CMD1_PORT_0, ioaddr);
754 }
755
756
757
758
759
760
761
762
763
764