xref: /inferno-os/os/boot/mpc/devether.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1 #include "u.h"
2 #include "lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 
8 #include "etherif.h"
9 
10 static Ctlr ether[MaxEther];
11 
12 static struct {
13 	char	*type;
14 	int	(*reset)(Ctlr*);
15 } cards[] = {
16 	{ "SCC", sccethreset, },
17 	{ "SCC2", sccethreset, },
18 	{ 0, }
19 };
20 
21 int
22 etherinit(void)
23 {
24 	Ctlr *ctlr;
25 	int ctlrno, i, mask, n;
26 
27 	mask = 0;
28 	for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
29 		ctlr = &ether[ctlrno];
30 		memset(ctlr, 0, sizeof(Ctlr));
31 		if(isaconfig("ether", ctlrno, &ctlr->card) == 0)
32 			continue;
33 		for(n = 0; cards[n].type; n++){
34 			if(strcmp(cards[n].type, ctlr->card.type))
35 				continue;
36 			ctlr->ctlrno = ctlrno;
37 			if((*cards[n].reset)(ctlr))
38 				break;
39 
40 			ctlr->iq = qopen(16*1024, 1, 0, 0);
41 			ctlr->oq = qopen(16*1024, 1, 0, 0);
42 
43 			ctlr->present = 1;
44 			mask |= 1<<ctlrno;
45 
46 			print("ether%d: %s: port 0x%luX irq %d",
47 				ctlr->ctlrno, ctlr->card.type, ctlr->card.port, ctlr->card.irq);
48 			if(ctlr->card.mem)
49 				print(" addr 0x%luX", PADDR(ctlr->card.mem));
50 			if(ctlr->card.size)
51 				print(" size 0x%luX", ctlr->card.size);
52 			print(":");
53 			for(i = 0; i < sizeof(ctlr->card.ea); i++)
54 				print(" %2.2uX", ctlr->card.ea[i]);
55 			print("\n"); uartwait();
56 			setvec(VectorPIC + ctlr->card.irq, ctlr->card.intr, ctlr);
57 			break;
58 		}
59 	}
60 
61 	return mask;
62 }
63 
64 static Ctlr*
65 attach(int ctlrno)
66 {
67 	Ctlr *ctlr;
68 
69 	if(ctlrno >= MaxEther || ether[ctlrno].present == 0)
70 		return 0;
71 
72 	ctlr = &ether[ctlrno];
73 	if(ctlr->present == 1){
74 		ctlr->present = 2;
75 		(*ctlr->card.attach)(ctlr);
76 	}
77 
78 	return ctlr;
79 }
80 
81 uchar*
82 etheraddr(int ctlrno)
83 {
84 	Ctlr *ctlr;
85 
86 	if((ctlr = attach(ctlrno)) == 0)
87 		return 0;
88 
89 	return ctlr->card.ea;
90 }
91 
92 int
93 etherrxpkt(int ctlrno, Etherpkt *pkt, int timo)
94 {
95 	int n;
96 	Ctlr *ctlr;
97 	Block *b;
98 	ulong start;
99 
100 	if((ctlr = attach(ctlrno)) == 0)
101 		return 0;
102 
103 	start = m->ticks;
104 	while((b = qget(ctlr->iq)) == 0){
105 		if(TK2MS(m->ticks - start) >= timo){
106 			/*
107 			print("ether%d: rx timeout\n", ctlrno);
108 			 */
109 			return 0;
110 		}
111 	}
112 
113 	n = BLEN(b);
114 	memmove(pkt, b->rp, n);
115 	freeb(b);
116 
117 	return n;
118 }
119 
120 int
121 etheriq(Ctlr *ctlr, Block *b, int freebp)
122 {
123 	if(memcmp(((Etherpkt*)b->rp)->d, ctlr->card.ea, Eaddrlen) != 0 &&
124 	   memcmp(((Etherpkt*)b->rp)->d, broadcast, Eaddrlen) != 0){
125 		if(freebp)
126 			freeb(b);
127 		return 0;
128 	}
129 	qbwrite(ctlr->iq, b);
130 	return 1;
131 }
132 
133 int
134 ethertxpkt(int ctlrno, Etherpkt *pkt, int len, int)
135 {
136 	Ctlr *ctlr;
137 	Block *b;
138 	int s;
139 
140 	if((ctlr = attach(ctlrno)) == 0)
141 		return 0;
142 
143 	if(qlen(ctlr->oq) > 16*1024){
144 		print("ether%d: tx queue full\n", ctlrno);
145 		return 0;
146 	}
147 	b = iallocb(sizeof(Etherpkt));
148 	memmove(b->wp, pkt, len);
149 	memmove(((Etherpkt*)b->wp)->s, ctlr->card.ea, Eaddrlen);
150 	b->wp += len;
151 	qbwrite(ctlr->oq, b);
152 	s = splhi();
153 	(*ctlr->card.transmit)(ctlr);
154 	splx(s);
155 
156 	return 1;
157 }
158