etherif.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. #include "all.h"
  2. #include "io.h"
  3. #include "mem.h"
  4. #include "../ip/ip.h"
  5. #include "etherif.h"
  6. #define dprint(...) /* print(__VA_ARGS__) */
  7. extern int etherga620reset(Ether*);
  8. extern int ether21140reset(Ether*);
  9. extern int etherelnk3reset(Ether*);
  10. extern int etheri82557reset(Ether*);
  11. extern int igbepnp(Ether *);
  12. extern int dp83815reset(Ether*);
  13. extern int dp83820pnp(Ether*);
  14. extern int rtl8139pnp(Ether*);
  15. extern int rtl8169pnp(Ether*);
  16. static struct
  17. {
  18. char* type;
  19. int (*reset)(Ether*);
  20. } etherctlr[] =
  21. {
  22. { "21140", ether21140reset, },
  23. { "2114x", ether21140reset, },
  24. { "3C509", etherelnk3reset, },
  25. { "83815", dp83815reset, },
  26. { "dp83820", dp83820pnp, },
  27. { "elnk3", etherelnk3reset, },
  28. { "ga620", etherga620reset, },
  29. { "i82557", etheri82557reset, },
  30. { "igbe", igbepnp, },
  31. { "rtl8139", rtl8139pnp, },
  32. { "rtl8169", rtl8169pnp, },
  33. { 0, },
  34. };
  35. static Ether etherif[MaxEther];
  36. void
  37. etheriq(Ether* ether, Msgbuf* mb)
  38. {
  39. ilock(&ether->rqlock);
  40. if(ether->rqhead)
  41. ether->rqtail->next = mb;
  42. else
  43. ether->rqhead = mb;
  44. ether->rqtail = mb;
  45. mb->next = 0;
  46. iunlock(&ether->rqlock);
  47. wakeup(&ether->rqr);
  48. }
  49. static int
  50. isinput(void* arg)
  51. {
  52. return ((Ether*)arg)->rqhead != 0;
  53. }
  54. #include "compat.h"
  55. static void
  56. etheri(void)
  57. {
  58. Ether *ether;
  59. Ifc *ifc;
  60. Msgbuf *mb;
  61. Enpkt *p;
  62. ether = getarg();
  63. ifc = &ether->ifc;
  64. print("ether%di: %E %I\n", ether->ctlrno, ether->ifc.ea, ether->ifc.ipa);
  65. (*ether->attach)(ether);
  66. for(;;) {
  67. while(!isinput(ether))
  68. sleep(&ether->rqr, isinput, ether);
  69. ilock(&ether->rqlock);
  70. if(ether->rqhead == 0) {
  71. iunlock(&ether->rqlock);
  72. continue;
  73. }
  74. mb = ether->rqhead;
  75. ether->rqhead = mb->next;
  76. iunlock(&ether->rqlock);
  77. p = (Enpkt*)mb->data;
  78. switch(nhgets(p->type)){
  79. case Arptype:
  80. arpreceive(p, mb->count, ifc);
  81. break;
  82. case Iptype:
  83. ipreceive(p, mb->count, ifc);
  84. ifc->rxpkt++;
  85. ifc->work[0].count++;
  86. ifc->work[1].count++;
  87. ifc->work[2].count++;
  88. ifc->rate[0].count += mb->count;
  89. ifc->rate[1].count += mb->count;
  90. ifc->rate[2].count += mb->count;
  91. break;
  92. }
  93. mbfree(mb);
  94. }
  95. }
  96. static void
  97. ethero(void)
  98. {
  99. Ether *ether;
  100. Ifc *ifc;
  101. Msgbuf *mb;
  102. int len;
  103. ether = getarg();
  104. ifc = &ether->ifc;
  105. print("ether%do: %E %I\n", ether->ctlrno, ifc->ea, ifc->ipa);
  106. for(;;) {
  107. for(;;) {
  108. mb = recv(ifc->reply, 0);
  109. if(mb != nil)
  110. break;
  111. }
  112. if(mb->data == 0) {
  113. print("ether%do: pkt nil cat=%d free=%d\n",
  114. ether->ctlrno, mb->category, mb->flags&FREE);
  115. if(!(mb->flags & FREE))
  116. mbfree(mb);
  117. continue;
  118. }
  119. len = mb->count;
  120. if(len > ETHERMAXTU) {
  121. print("ether%do: pkt too big - %d\n", ether->ctlrno, len);
  122. mbfree(mb);
  123. continue;
  124. }
  125. if(len < ETHERMINTU) {
  126. memset(mb->data+len, 0, ETHERMINTU-len);
  127. mb->count = len = ETHERMINTU;
  128. }
  129. memmove(((Enpkt*)(mb->data))->s, ifc->ea, sizeof(ifc->ea));
  130. ilock(&ether->tqlock);
  131. if(ether->tqhead)
  132. ether->tqtail->next = mb;
  133. else
  134. ether->tqhead = mb;
  135. ether->tqtail = mb;
  136. mb->next = 0;
  137. iunlock(&ether->tqlock);
  138. (*ether->transmit)(ether);
  139. ifc->work[0].count++;
  140. ifc->work[1].count++;
  141. ifc->work[2].count++;
  142. ifc->rate[0].count += len;
  143. ifc->rate[1].count += len;
  144. ifc->rate[2].count += len;
  145. ifc->txpkt++;
  146. }
  147. }
  148. Msgbuf*
  149. etheroq(Ether* ether)
  150. {
  151. Msgbuf *mb;
  152. mb = nil;
  153. ilock(&ether->tqlock);
  154. if(ether->tqhead){
  155. mb = ether->tqhead;
  156. ether->tqhead = mb->next;
  157. }
  158. iunlock(&ether->tqlock);
  159. return mb;
  160. }
  161. static void
  162. cmd_state(int, char*[])
  163. {
  164. Ether *ether;
  165. Ifc *ifc;
  166. for(ether = &etherif[0]; ether < &etherif[MaxEther]; ether++){
  167. if(ether->mbps == 0)
  168. continue;
  169. ifc = &ether->ifc;
  170. if(!isvalidip(ifc->ipa))
  171. continue;
  172. print("ether stats %d\n", ether->ctlrno);
  173. print(" work =%7W%7W%7W pkts\n", ifc->work+0, ifc->work+1, ifc->work+2);
  174. print(" rate =%7W%7W%7W tBps\n", ifc->rate+0, ifc->rate+1, ifc->rate+2);
  175. print(" err = %3ld rc %3ld sum\n", ifc->rcverr, ifc->sumerr);
  176. }
  177. }
  178. void
  179. etherstart(void)
  180. {
  181. Ether *ether;
  182. Ifc *ifc;
  183. int anystarted;
  184. char buf[100], *p;
  185. anystarted = 0;
  186. for(ether = &etherif[0]; ether < &etherif[MaxEther]; ether++){
  187. if(ether->mbps == 0)
  188. continue;
  189. ifc = &ether->ifc;
  190. lock(ifc);
  191. getipa(ifc, ether->ctlrno);
  192. if(!isvalidip(ifc->ipa)){
  193. unlock(ifc);
  194. ether->mbps = 0;
  195. continue;
  196. }
  197. if(ifc->reply == 0){
  198. dofilter(ifc->work+0, C0a, C0b, 1);
  199. dofilter(ifc->work+1, C1a, C1b, 1);
  200. dofilter(ifc->work+2, C2a, C2b, 1);
  201. dofilter(ifc->rate+0, C0a, C0b, 1000);
  202. dofilter(ifc->rate+1, C1a, C1b, 1000);
  203. dofilter(ifc->rate+2, C2a, C2b, 1000);
  204. ifc->reply = newqueue(Nqueue);
  205. }
  206. unlock(ifc);
  207. sprint(ether->oname, "ether%do", ether->ctlrno);
  208. userinit(ethero, ether, ether->oname);
  209. sprint(ether->iname, "ether%di", ether->ctlrno);
  210. userinit(etheri, ether, ether->iname);
  211. ifc->next = enets;
  212. enets = ifc;
  213. anystarted++;
  214. }
  215. if(anystarted){
  216. cmd_install("state", "-- ether stats", cmd_state);
  217. arpstart();
  218. if((p = getconf("route")) && strlen(p) < sizeof(buf)-7){
  219. sprint(buf, "route %s", p);
  220. cmd_exec(buf);
  221. }
  222. }
  223. }
  224. static int
  225. parseether(uchar *to, char *from)
  226. {
  227. char nip[4];
  228. char *p;
  229. int i;
  230. p = from;
  231. while(*p == ' ')
  232. ++p;
  233. for(i = 0; i < 6; i++){
  234. if(*p == 0)
  235. return -1;
  236. nip[0] = *p++;
  237. if(*p == 0)
  238. return -1;
  239. nip[1] = *p++;
  240. nip[2] = 0;
  241. to[i] = strtoul(nip, 0, 16);
  242. if(*p == ':')
  243. p++;
  244. }
  245. return 0;
  246. }
  247. void
  248. etherinit(void)
  249. {
  250. Ether *ether;
  251. int i, n, ctlrno;
  252. for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
  253. ether = &etherif[ctlrno];
  254. memset(ether, 0, sizeof(Ether));
  255. if(!isaconfig("ether", ctlrno, ether))
  256. continue;
  257. for(n = 0; etherctlr[n].type; n++){
  258. if(cistrcmp(etherctlr[n].type, ether->type))
  259. continue;
  260. dprint("FOUND ether %s\n", etherctlr[n].type);
  261. ether->ctlrno = ctlrno;
  262. ether->tbdf = BUSUNKNOWN;
  263. for(i = 0; i < ether->nopt; i++){
  264. if(strncmp(ether->opt[i], "ea=", 3))
  265. continue;
  266. if(parseether(ether->ea, &ether->opt[i][3]) == -1)
  267. memset(ether->ea, 0, Easize);
  268. }
  269. dprint(" reset ... ");
  270. if((*etherctlr[n].reset)(ether)){
  271. dprint("fail\n");
  272. break;
  273. }
  274. dprint("okay\n");
  275. if(ether->irq == 2)
  276. ether->irq = 9;
  277. setvec(Int0vec + ether->irq, ether->interrupt, ether);
  278. memmove(ether->ifc.ea, ether->ea, sizeof(ether->ea));
  279. print("ether%d: %s: %dMbps port 0x%lux irq %ld",
  280. ctlrno, ether->type, ether->mbps, ether->port, ether->irq);
  281. if(ether->mem)
  282. print(" addr 0x%lux", ether->mem & ~KZERO);
  283. if(ether->size)
  284. print(" size 0x%lux", ether->size);
  285. print(": ");
  286. for(i = 0; i < sizeof(ether->ea); i++)
  287. print("%2.2ux", ether->ea[i]);
  288. print("\n");
  289. break;
  290. }
  291. }
  292. }