ether.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "io.h"
  15. #include "ip.h"
  16. #include "etherif.h"
  17. static Ether ether[MaxEther];
  18. extern int amd79c970reset(Ether*);
  19. extern int ether2114xreset(Ether*);
  20. extern int etherbcm4401pnp(Ether*);
  21. extern int i82557reset(Ether*);
  22. extern int i82563pnp(Ether*);
  23. extern int igbepnp(Ether *);
  24. extern int rtl8139pnp(Ether*);
  25. extern int rtl8169pnp(Ether*);
  26. extern int vgbepnp(Ether*);
  27. struct {
  28. char *type;
  29. int (*reset)(Ether*);
  30. int noprobe;
  31. } ethercards[] = {
  32. { "21140", ether2114xreset, 0, },
  33. { "2114x", ether2114xreset, 0, },
  34. { "bcm4401", etherbcm4401pnp, 0, },
  35. { "i82557", i82557reset, 0, },
  36. { "i82563", i82563pnp, 0, },
  37. { "igbe", igbepnp, 0, },
  38. { "RTL8139", rtl8139pnp, 0, },
  39. { "RTL8169", rtl8169pnp, 0, },
  40. { "AMD79C970", amd79c970reset, 0, },
  41. { "vgbe", vgbepnp, 0, },
  42. { 0, }
  43. };
  44. static void xetherdetach(void);
  45. int
  46. etherinit(void)
  47. {
  48. Ether *ctlr;
  49. int ctlrno, i, mask, n, x;
  50. fmtinstall('E', eipfmt);
  51. etherdetach = xetherdetach;
  52. mask = 0;
  53. for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
  54. ctlr = &ether[ctlrno];
  55. memset(ctlr, 0, sizeof(Ether));
  56. if(iniread && isaconfig("ether", ctlrno, ctlr) == 0)
  57. continue;
  58. for(n = 0; ethercards[n].type; n++){
  59. if(!iniread){
  60. if(ethercards[n].noprobe)
  61. continue;
  62. memset(ctlr, 0, sizeof(Ether));
  63. ctlr->type = ethercards[n].type;
  64. }
  65. else if(cistrcmp(ethercards[n].type, ctlr->type))
  66. continue;
  67. ctlr->ctlrno = ctlrno;
  68. x = splhi();
  69. if((*ethercards[n].reset)(ctlr)){
  70. splx(x);
  71. if(iniread)
  72. break;
  73. else
  74. continue;
  75. }
  76. ctlr->state = 1;
  77. mask |= 1<<ctlrno;
  78. if(ctlr->irq == 2)
  79. ctlr->irq = 9;
  80. setvec(VectorPIC + ctlr->irq, ctlr->interrupt, ctlr);
  81. print("ether#%d: %s: port 0x%luX irq %lud",
  82. ctlr->ctlrno, ctlr->type, ctlr->port, ctlr->irq);
  83. if(ctlr->mem)
  84. print(" addr 0x%luX", ctlr->mem & ~KZERO);
  85. if(ctlr->size)
  86. print(" size 0x%luX", ctlr->size);
  87. print(": %E\n", ctlr->ea);
  88. if(ctlr->nrb == 0)
  89. ctlr->nrb = Nrb;
  90. ctlr->rb = ialloc(sizeof(RingBuf)*ctlr->nrb, 0);
  91. if(ctlr->ntb == 0)
  92. ctlr->ntb = Ntb;
  93. ctlr->tb = ialloc(sizeof(RingBuf)*ctlr->ntb, 0);
  94. ctlr->rh = 0;
  95. ctlr->ri = 0;
  96. for(i = 0; i < ctlr->nrb; i++)
  97. ctlr->rb[i].owner = Interface;
  98. ctlr->th = 0;
  99. ctlr->ti = 0;
  100. for(i = 0; i < ctlr->ntb; i++)
  101. ctlr->tb[i].owner = Host;
  102. splx(x);
  103. break;
  104. }
  105. }
  106. return mask;
  107. }
  108. void
  109. etherinitdev(int i, char *s)
  110. {
  111. sprint(s, "ether%d", i);
  112. }
  113. void
  114. etherprintdevs(int i)
  115. {
  116. print(" ether%d", i);
  117. }
  118. static Ether*
  119. attach(int ctlrno)
  120. {
  121. Ether *ctlr;
  122. if(ctlrno >= MaxEther || ether[ctlrno].state == 0)
  123. return 0;
  124. ctlr = &ether[ctlrno];
  125. if(ctlr->state == 1){
  126. ctlr->state = 2;
  127. (*ctlr->attach)(ctlr);
  128. }
  129. return ctlr;
  130. }
  131. static void
  132. xetherdetach(void)
  133. {
  134. Ether *ctlr;
  135. int ctlrno, x;
  136. x = splhi();
  137. for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
  138. ctlr = &ether[ctlrno];
  139. if(ctlr->detach && ctlr->state != 0)
  140. ctlr->detach(ctlr);
  141. }
  142. splx(x);
  143. }
  144. uint8_t*
  145. etheraddr(int ctlrno)
  146. {
  147. Ether *ctlr;
  148. if((ctlr = attach(ctlrno)) == 0)
  149. return 0;
  150. return ctlr->ea;
  151. }
  152. static int
  153. wait(RingBuf* ring, uint8_t owner, int timo)
  154. {
  155. uint32_t start;
  156. extern void hlt(void);
  157. start = machp()->ticks;
  158. while(TK2MS(machp()->ticks - start) < timo){
  159. if(ring->owner != owner)
  160. return 1;
  161. hlt();
  162. }
  163. return 0;
  164. }
  165. int
  166. etherrxpkt(int ctlrno, Etherpkt* pkt, int timo)
  167. {
  168. int n;
  169. Ether *ctlr;
  170. RingBuf *ring;
  171. if((ctlr = attach(ctlrno)) == 0)
  172. return 0;
  173. ring = &ctlr->rb[ctlr->rh];
  174. if(wait(ring, Interface, timo) == 0){
  175. if(debug)
  176. print("ether%d: rx timeout\n", ctlrno);
  177. return 0;
  178. }
  179. n = ring->len;
  180. memmove(pkt, ring->pkt, n);
  181. ring->owner = Interface;
  182. ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
  183. return n;
  184. }
  185. int
  186. etherrxflush(int ctlrno)
  187. {
  188. int n;
  189. Ether *ctlr;
  190. RingBuf *ring;
  191. if((ctlr = attach(ctlrno)) == 0)
  192. return 0;
  193. n = 0;
  194. for(;;){
  195. ring = &ctlr->rb[ctlr->rh];
  196. if(wait(ring, Interface, 100) == 0)
  197. break;
  198. ring->owner = Interface;
  199. ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
  200. n++;
  201. }
  202. return n;
  203. }
  204. int
  205. ethertxpkt(int ctlrno, Etherpkt* pkt, int len, int)
  206. {
  207. Ether *ctlr;
  208. RingBuf *ring;
  209. int s;
  210. if((ctlr = attach(ctlrno)) == 0)
  211. return 0;
  212. ring = &ctlr->tb[ctlr->th];
  213. if(wait(ring, Interface, 1000) == 0){
  214. print("ether%d: tx buffer timeout\n", ctlrno);
  215. return 0;
  216. }
  217. memmove(pkt->s, ctlr->ea, Eaddrlen);
  218. if(debug)
  219. print("%E to %E...\n", pkt->s, pkt->d);
  220. memmove(ring->pkt, pkt, len);
  221. if(len < ETHERMINTU){
  222. memset(ring->pkt+len, 0, ETHERMINTU-len);
  223. len = ETHERMINTU;
  224. }
  225. ring->len = len;
  226. ring->owner = Interface;
  227. ctlr->th = NEXT(ctlr->th, ctlr->ntb);
  228. s = splhi();
  229. (*ctlr->transmit)(ctlr);
  230. splx(s);
  231. return 1;
  232. }