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 #include "ip.h" 8 9 #include "etherif.h" 10 11 static Ether ether[MaxEther]; 12 13 extern int ether2114xreset(Ether*); 14 extern int elnk3reset(Ether*); 15 extern int i82557reset(Ether*); 16 extern int igbepnp(Ether *); 17 extern int i82563pnp(Ether *); 18 extern int elnk3reset(Ether*); 19 extern int ether589reset(Ether*); 20 extern int ne2000reset(Ether*); 21 extern int wd8003reset(Ether*); 22 extern int ec2treset(Ether*); 23 extern int amd79c970reset(Ether*); 24 extern int rtl8139pnp(Ether*); 25 extern int rtl8169pnp(Ether*); 26 extern int ether83815reset(Ether*); 27 extern int rhinepnp(Ether*); 28 extern int ga620pnp(Ether*); 29 extern int dp83820pnp(Ether*); 30 31 struct { 32 char *type; 33 int (*reset)(Ether*); 34 int noprobe; 35 } ethercards[] = { 36 { "21140", ether2114xreset, 0, }, 37 { "2114x", ether2114xreset, 0, }, 38 { "i82557", i82557reset, 0, }, 39 { "igbe", igbepnp, 0, }, 40 { "i82563",i82563pnp, 0, }, 41 { "igbepcie",i82563pnp, 0, }, 42 { "elnk3", elnk3reset, 0, }, 43 { "3C509", elnk3reset, 0, }, 44 { "3C575", elnk3reset, 0, }, 45 { "3C589", ether589reset, 1, }, 46 { "3C562", ether589reset, 1, }, 47 { "589E", ether589reset, 1, }, 48 { "NE2000", ne2000reset, 0, }, 49 { "WD8003", wd8003reset, 1, }, 50 { "EC2T", ec2treset, 0, }, 51 { "AMD79C970", amd79c970reset, 0, }, 52 { "RTL8139", rtl8139pnp, 0, }, 53 { "RTL8169", rtl8169pnp, 0, }, 54 { "83815", ether83815reset, 0, }, 55 { "rhine", rhinepnp, 0, }, 56 { "vt6102", rhinepnp, 0, }, 57 { "GA620", ga620pnp, 0, }, 58 { "83820", dp83820pnp, 0, }, 59 { "dp83820", dp83820pnp, 0, }, 60 61 { 0, } 62 }; 63 64 static void xetherdetach(void); 65 66 int 67 etherinit(void) 68 { 69 Ether *ctlr; 70 int ctlrno, i, mask, n, x; 71 72 fmtinstall('E', eipfmt); 73 74 etherdetach = xetherdetach; 75 mask = 0; 76 for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){ 77 ctlr = ðer[ctlrno]; 78 memset(ctlr, 0, sizeof(Ether)); 79 if(iniread && isaconfig("ether", ctlrno, ctlr) == 0) 80 continue; 81 82 for(n = 0; ethercards[n].type; n++){ 83 if(!iniread){ 84 if(ethercards[n].noprobe) 85 continue; 86 memset(ctlr, 0, sizeof(Ether)); 87 strcpy(ctlr->type, ethercards[n].type); 88 } 89 else if(cistrcmp(ethercards[n].type, ctlr->type)) 90 continue; 91 ctlr->ctlrno = ctlrno; 92 93 x = splhi(); 94 if((*ethercards[n].reset)(ctlr)){ 95 splx(x); 96 if(iniread) 97 break; 98 else 99 continue; 100 } 101 102 ctlr->state = 1; /* card found */ 103 mask |= 1<<ctlrno; 104 if(ctlr->irq == 2) 105 ctlr->irq = 9; 106 setvec(VectorPIC + ctlr->irq, ctlr->interrupt, ctlr); 107 108 print("ether#%d: %s: port 0x%luX irq %lud", 109 ctlr->ctlrno, ctlr->type, ctlr->port, ctlr->irq); 110 if(ctlr->mem) 111 print(" addr 0x%luX", ctlr->mem & ~KZERO); 112 if(ctlr->size) 113 print(" size 0x%luX", ctlr->size); 114 print(": %E\n", ctlr->ea); 115 116 if(ctlr->nrb == 0) 117 ctlr->nrb = Nrb; 118 ctlr->rb = ialloc(sizeof(RingBuf)*ctlr->nrb, 0); 119 if(ctlr->ntb == 0) 120 ctlr->ntb = Ntb; 121 ctlr->tb = ialloc(sizeof(RingBuf)*ctlr->ntb, 0); 122 123 ctlr->rh = 0; 124 ctlr->ri = 0; 125 for(i = 0; i < ctlr->nrb; i++) 126 ctlr->rb[i].owner = Interface; 127 128 ctlr->th = 0; 129 ctlr->ti = 0; 130 for(i = 0; i < ctlr->ntb; i++) 131 ctlr->tb[i].owner = Host; 132 133 splx(x); 134 break; 135 } 136 } 137 138 return mask; 139 } 140 141 void 142 etherinitdev(int i, char *s) 143 { 144 sprint(s, "ether%d", i); 145 } 146 147 void 148 etherprintdevs(int i) 149 { 150 print(" ether%d", i); 151 } 152 153 static Ether* 154 attach(int ctlrno) 155 { 156 Ether *ctlr; 157 158 if(ctlrno >= MaxEther || ether[ctlrno].state == 0) 159 return 0; 160 161 ctlr = ðer[ctlrno]; 162 if(ctlr->state == 1){ /* card found? */ 163 ctlr->state = 2; /* attaching */ 164 (*ctlr->attach)(ctlr); 165 } 166 167 return ctlr; 168 } 169 170 static void 171 xetherdetach(void) 172 { 173 Ether *ctlr; 174 int ctlrno, x; 175 176 x = splhi(); 177 for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){ 178 ctlr = ðer[ctlrno]; 179 if(ctlr->detach && ctlr->state != 0) /* found | attaching? */ 180 ctlr->detach(ctlr); 181 } 182 splx(x); 183 } 184 185 uchar* 186 etheraddr(int ctlrno) 187 { 188 Ether *ctlr; 189 190 if((ctlr = attach(ctlrno)) == 0) 191 return 0; 192 193 return ctlr->ea; 194 } 195 196 static int 197 wait(RingBuf* ring, uchar owner, int timo) 198 { 199 ulong start; 200 201 start = m->ticks; 202 while(TK2MS(m->ticks - start) < timo){ 203 if(ring->owner != owner) 204 return 1; 205 } 206 207 return 0; 208 } 209 210 int 211 etherrxpkt(int ctlrno, Etherpkt* pkt, int timo) 212 { 213 int n; 214 Ether *ctlr; 215 RingBuf *ring; 216 217 if((ctlr = attach(ctlrno)) == 0) 218 return 0; 219 220 ring = &ctlr->rb[ctlr->rh]; 221 if(wait(ring, Interface, timo) == 0){ 222 if(debug) 223 print("ether%d: rx timeout\n", ctlrno); 224 return 0; 225 } 226 227 n = ring->len; 228 memmove(pkt, ring->pkt, n); 229 ring->owner = Interface; 230 ctlr->rh = NEXT(ctlr->rh, ctlr->nrb); 231 232 return n; 233 } 234 235 int 236 etherrxflush(int ctlrno) 237 { 238 int n; 239 Ether *ctlr; 240 RingBuf *ring; 241 242 if((ctlr = attach(ctlrno)) == 0) 243 return 0; 244 245 n = 0; 246 for(;;){ 247 ring = &ctlr->rb[ctlr->rh]; 248 if(wait(ring, Interface, 100) == 0) 249 break; 250 251 ring->owner = Interface; 252 ctlr->rh = NEXT(ctlr->rh, ctlr->nrb); 253 n++; 254 } 255 256 return n; 257 } 258 259 int 260 ethertxpkt(int ctlrno, Etherpkt* pkt, int len, int) 261 { 262 Ether *ctlr; 263 RingBuf *ring; 264 int s; 265 266 if((ctlr = attach(ctlrno)) == 0) 267 return 0; 268 269 ring = &ctlr->tb[ctlr->th]; 270 if(wait(ring, Interface, 1000) == 0){ 271 print("ether%d: tx buffer timeout\n", ctlrno); 272 return 0; 273 } 274 275 memmove(pkt->s, ctlr->ea, Eaddrlen); 276 if(debug) 277 print("%E to %E...\n", pkt->s, pkt->d); 278 memmove(ring->pkt, pkt, len); 279 if(len < ETHERMINTU){ 280 memset(ring->pkt+len, 0, ETHERMINTU-len); 281 len = ETHERMINTU; 282 } 283 ring->len = len; 284 ring->owner = Interface; 285 ctlr->th = NEXT(ctlr->th, ctlr->ntb); 286 s = splhi(); 287 (*ctlr->transmit)(ctlr); 288 splx(s); 289 290 return 1; 291 } 292