ether.c 5.4 KB

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