|
|
1.1 root 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 "ether.h"
9:
10: static Ctlr ether[MaxEther];
11:
12: static struct {
13: char *type;
14: int (*reset)(Ctlr*);
15: } cards[] = {
16: { "NE2000", ne2000reset, },
17: { "NE3210", ne3210reset, },
18: { "3C509", tcm509reset, },
19: { "WD8003", wd8003reset, },
20: { 0, }
21: };
22:
23: int
24: etherinit(void)
25: {
26: Ctlr *ctlr;
27: int ctlrno, i, mask, n;
28:
29: mask = 0;
30: for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
31: ctlr = ðer[ctlrno];
32: memset(ctlr, 0, sizeof(Ctlr));
33: if(isaconfig("ether", ctlrno, &ctlr->card) == 0)
34: continue;
35: for(n = 0; cards[n].type; n++){
36: if(strcmp(cards[n].type, ctlr->card.type))
37: continue;
38: ctlr->ctlrno = ctlrno;
39: if((*cards[n].reset)(ctlr))
40: break;
41:
42: ctlr->present = 1;
43: mask |= 1<<ctlrno;
44: if(ctlr->card.irq == 2)
45: ctlr->card.irq = 9;
46: setvec(Int0vec + ctlr->card.irq, ctlr->card.intr, ctlr);
47:
48: print("ether%d: %s: port %lux irq %d addr %lux size %d width %d:",
49: ctlr->ctlrno, ctlr->card.type, ctlr->card.port, ctlr->card.irq,
50: ctlr->card.mem, ctlr->card.size, ctlr->card.bit16 ? 16: 8);
51: for(i = 0; i < sizeof(ctlr->card.ea); i++)
52: print(" %2.2ux", ctlr->card.ea[i]);
53: print("\n");
54:
55: if(ctlr->nrb == 0)
56: ctlr->nrb = Nrb;
57: ctlr->rb = ialloc(sizeof(RingBuf)*ctlr->nrb, 0);
58: if(ctlr->ntb == 0)
59: ctlr->ntb = Ntb;
60: ctlr->tb = ialloc(sizeof(RingBuf)*ctlr->ntb, 0);
61:
62: ctlr->rh = 0;
63: ctlr->ri = 0;
64: for(i = 0; i < ctlr->nrb; i++)
65: ctlr->rb[i].owner = Interface;
66:
67: ctlr->th = 0;
68: ctlr->ti = 0;
69: for(i = 0; i < ctlr->ntb; i++)
70: ctlr->tb[i].owner = Host;
71:
72: break;
73: }
74: }
75:
76: return mask;
77: }
78:
79: static Ctlr*
80: attach(int ctlrno)
81: {
82: Ctlr *ctlr;
83:
84: if(ctlrno >= MaxEther || ether[ctlrno].present == 0)
85: return 0;
86:
87: ctlr = ðer[ctlrno];
88: if(ctlr->present == 1){
89: ctlr->present = 2;
90: (*ctlr->card.attach)(ctlr);
91: }
92:
93: return ctlr;
94: }
95:
96: uchar*
97: etheraddr(int ctlrno)
98: {
99: Ctlr *ctlr;
100:
101: if((ctlr = attach(ctlrno)) == 0)
102: return 0;
103:
104: return ctlr->card.ea;
105: }
106:
107: static int
108: wait(RingBuf *ring, uchar owner, int timo)
109: {
110: ulong start;
111:
112: start = m->ticks;
113: while(TK2MS(m->ticks - start) < timo){
114: if(ring->owner != owner)
115: return 1;
116: }
117:
118: return 0;
119: }
120:
121: int
122: etherrxpkt(int ctlrno, Etherpkt *pkt, int timo)
123: {
124: int n;
125: Ctlr *ctlr;
126: RingBuf *ring;
127:
128: if((ctlr = attach(ctlrno)) == 0)
129: return 0;
130:
131: ring = &ctlr->rb[ctlr->rh];
132: if(wait(ring, Interface, timo) == 0){
133: print("ether%d: rx timeout\n", ctlrno);
134: return 0;
135: }
136:
137: n = ring->len;
138: memmove(pkt, ring->pkt, n);
139: ring->owner = Interface;
140: ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
141:
142: return n;
143: }
144:
145: int
146: ethertxpkt(int ctlrno, Etherpkt *pkt, int len, int timo)
147: {
148: Ctlr *ctlr;
149: RingBuf *ring;
150:
151: if((ctlr = attach(ctlrno)) == 0)
152: return 0;
153:
154: ring = &ctlr->tb[ctlr->th];
155: memmove(ring->pkt, pkt, len);
156: if(len < ETHERMINTU){
157: memset(ring->pkt+len, 0, ETHERMINTU-len);
158: len = ETHERMINTU;
159: }
160: ring->len = len;
161: ring->owner = Interface;
162: ctlr->th = NEXT(ctlr->th, ctlr->ntb);
163: (*ctlr->card.transmit)(ctlr);
164:
165: if(wait(ring, Interface, timo) == 0){
166: print("ether%d: rx timeout\n", ctlrno);
167: return 0;
168: }
169:
170: return 1;
171: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.