1 /*
2 * alternate implementation with kprocs (TODO)
3 */
4
5 Rendez oqgotpkt;
6 Rendez txdmadone;
7 Rendez gotfifotxq;
8 Rendez txdone;
9
10 int
isdmaready(Ether * ether)11 isdmaready(Ether *ether)
12 {
13 Block *bp;
14 Queue *q;
15
16 q = ether->oq;
17 if (!qcanread(q))
18 return 0;
19 bp = qget(q);
20 qputback(q, bp);
21 return (frp->tdfv & Wordcnt) >=
22 ROUNDUP(padpktlen(BLEN(bp)), BY2WD) / BY2WD;
23 }
24
25 void
txdmaproc(Ether * ether)26 txdmaproc(Ether *ether) /* owns dma chan 1 */
27 {
28 unsigned ruplen;
29 Block *bp;
30
31 for(;;) {
32 /* sleep until oq has pkt & tx fifo has room for it */
33 sleep(&oqgotpkt, isdmaready, ether);
34
35 bp = qget(ether->oq);
36 ruplen = ROUNDUP(padpktlen(BLEN(bp)), BY2WD);
37
38 dmastart(Chan1, &frp->tdfd, bp->rp, ruplen, Sinc, dmatxdone);
39 sleep(&txdmadone);
40
41 addfifotxq(ether, bp);
42 wakeup(&gotfifotxq); /* have work for temac now */
43 }
44 }
45
46 int
istemacready(Ether * ether)47 istemacready(Ether *ether)
48 {
49 Ctlr *ctlr;
50
51 ctlr = ether->ctlr;
52 return ether->fifotxq != nil && !ctlr->xmitting;
53 }
54
55 void
txtemacproc(Ether * ether)56 txtemacproc(Ether *ether) /* owns temac transmitter */
57 {
58 Block *bp;
59
60 for(;;) {
61 /* sleep until txq has pkt & tx is idle */
62 sleep(&gotfifotxq, istemacready, ether);
63
64 bp = ether->fifotxq;
65 ether->fifotxq = bp->next;
66
67 kicktemac(ether);
68 sleep(&txdone);
69
70 free(bp);
71 wakeup(&oqgotpkt); /* might be work for dma1 now */
72 }
73 }
74
dmatxdone()75 dmatxdone()
76 {
77 // ...
78 wakeup(&txdmadone);
79 // ...
80 }
81
temactransmit(Ether * ether)82 temactransmit(Ether *ether)
83 {
84 // ...
85 wakeup(&oqgotpkt);
86 // ...
87 }
88
dmaintr()89 dmaintr()
90 {
91 // ...
92 wakeup(&oqgotpkt); /* if txfifo now has room */
93 wakeup(&txdmadone);
94 // ...
95 }
96
fifointr()97 fifointr()
98 {
99 // ...
100 wakeup(&txdone);
101 // ...
102 }
103