|
|
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.